임의의 정밀 나눗셈 구현


15

divide(int a, int b, int c)의 기본 10 값을 인쇄 하는 함수 를 구현하십시오 a/b. 부동 소수점 연산도 사용하지 않고 BigInteger/ BigDecimal또는 무엇이든지 해당 라이브러리를. 아래 포인트 4의 (가능한) 예외를 제외하고 c는 세트 내에 적어도 정확한 문자를 0123456789.인쇄해야합니다.

  1. ab모든 32 개 비트 정수가 될 수있다. 업데이트 : 골프 목적으로 입력을 64 비트 프리미티브로 사용하고 싶지만 전체 64 비트 범위의 데이터를 지원할 필요는 없습니다.
  2. 그렇지 않은 경우 c긍정적 인지 확인하지 않아도됩니다 (프로그램이 충돌하지 않기를 바랍니다).
  3. 지원되는 최소 상한 c500입니다. 프로그램이 c상기 값을 지원하지 않으면 500괜찮지 만, 지원하는 경우에도 괜찮습니다.
  4. 균등하게 나누는 숫자의 경우 여분의 0을 인쇄 c하거나 ( 의 값에 따라 ) 아무 것도 선택하지 않습니다.
  5. 몫으로 추가 작업을 수행하기 위해이 기능을 사용할 필요는 없습니다. 유일한 목표는 인쇄입니다.
  6. -1및 사이의 숫자 1는 행간을 인쇄할지 여부를 선택하는 것 0입니다. 그러나 이것은 선행 0을 인쇄하는 것이 허용되는 유일한 시나리오이며 이러한 0을 하나만 인쇄 할 수 있습니다.
  7. 마지막 소수점 자리에 원하는 반올림 / 바닥 / 천장 논리를 사용할 수 있습니다.
  8. 부정적인 답변을 얻으려면 선행을 인쇄해야합니다 -. 이 계산에는 포함되지 않습니다 c. 인쇄하지하고자하는 경우, 그것은 당신의 선택이다 , +또는 긍정적 인 답변 아무것도.
  9. 정수 나누기와 정수 계수가 모두 허용됩니다. 당신이 당신의 자신의 구현하도록 선택하지 않는 그러나, 당신이 프리미티브로 제한됩니다 것을 명심 BigInteger/의 BigDecimal코드 길이에 대한 어떤 계산 라이브러리를.
  10. 당신은 처리하지 않아도 b되는 0당신이 원하는 경우 수 있지만. 프로그램이 무한 루프에 들어가거나이면 충돌 b=0할 수 있으며 벌점을받지 않습니다.
  11. 주석마다 약간의 규칙 변경. 경기장이 수평을 유지 a하고 b32 비트 정수임을 보장하기 위해 64 비트 정수를 사용할 수 있습니다. 선택한 언어가 기본적으로 64 비트 정수를 초과하는 경우 해당 기능을 사용할 수 없습니다 (64 비트로 제한되어있는 것처럼 보임).
  12. 명확하지 않은 또 다른 요점 (현재 유효한 답변을 변경해서는 안 됨) : c인쇄 된 문자 수 또는 소수점 이하 공백으로 해석 될 수 있지만 프로그램은 c어떻게 든 관련 방식으로 사용해야합니다 인쇄 할 문자 수를 결정합니다. 다시 말해, divide(2,3,2)출력보다 훨씬 짧은 출력이어야합니다 divide(2,3,500). 에 관계없이 500자를 인쇄하는 것은 좋지 않습니다 c.
  13. 실제로 함수 이름은 신경 쓰지 않습니다. d골프 목적으로 괜찮습니다.

입력

함수 호출과 읽기가 stdin모두 허용됩니다. 에서 읽을 경우 stdin세트에없는 문자 [-0123456789]는 인수 구분 기호로 간주됩니다.

산출

stdout위에서 설명한대로 문자

에 대해 divide(2,3,5)다음은 모두 허용 가능한 출력입니다.

0.666
0.667
.6666
.6667
 0.666
 0.667
 .6666
 .6667
+0.666
+0.667
+.6666
+.6667

다른 예 : divide(371,3,5)다음은 모두 허용되는 출력입니다.

123.6
123.7
 123.6
 123.7
+123.6
+123.7
123.66666
123.66667
 123.66666
 123.66667
+123.66666
+123.66667

그리고에 대한 divide(371,-3,5)다음의 모든 허용 있습니다 :

-123.6
-123.7
-123.66666
-123.66667

레벨 플레이 필드를 위해 자신의 더 큰 구현을 롤링하지 않는 한 (기본 또는 다른) 사용할 수 있는 특정 최대 비트 길이 를 제공하는 것이 현명 할 수 있습니다 .a ) 일부 언어에서는 프리미티브의 비트 길이가 기본 구조와 b) 일부 언어에서는 큰 숫자 유형 기본 요소입니다.
Jonathan Van Matre


1
정확한 자릿수 는 어떻게 계산 합니까? 귀하의 예에서는 마지막 인수가 나타내는 것처럼 3 ~ 4 개를 보지만 5는 절대 보지 않습니다.
Howard

@Howard, 당신이 92,3,5대답했다면 예를 들면 다음과 같습니다30.67
durron597

1
btw 370 / 3 = 123.333 lol
izabera

답변:


5

자바, 92/128

void d(long a,int b,int c){if(a<0^b<0){a=-a;p('-');}for(p(a/b+".");c>0;c--)p((a=a%b*10)/b);}<T>void p(T x){System.out.print(x);}

나는 너무 즉흥적으로했다 a또는 b32 비트 양의 정수 만의 이유 것으로, 2147483647으로 계산 -2147483648로 될 수 a되었다 long. 이 부정적인 결과를 처리하는 더 좋은 방법,하지만 난 없음 (알 수 double의 아마 얻을 것 이를 위한 작업에 abs(a) < abs(b)그들이 가지고 -0있지만 1의 보수는 정밀도를 유지하는 것입니다).

왜 2 바이트 숫자입니까? 계산에는 92 바이트가 필요하고 인쇄 도우미에는 36 바이트가 필요했습니다 ( System.out.print일반적으로 Java는 그렇게 골치 아프지 않습니다).

public class Div {

    void d(long a, int b, int c) {
        if (a < 0 ^ b < 0) {
            a = -a;
            p('-');
        }
        for (p(a / b + "."); c > 0; c--) {
            p((a = a % b * 10) / b);
        }
    }

    <T> void p(T x) {
        System.out.print(x);
    }

    public static void main(String[] args) {
        final Div div = new Div();
        div.d(12345, 234, 20);
        div.p('\n');
        div.d(-12345, 234, 20);
        div.p('\n');
        div.d(234, 234, 20);
        div.p('\n');
        div.d(-234, 234, 20);
        div.p('\n');
        div.d(234, 12345, 20);
        div.p('\n');
        div.d(234, -12345, 20);
        div.p('\n');
        div.d(-234, 12345, 20);
        div.p('\n');
        div.d(-234, -12345, 20);
        div.p('\n');
        div.d(-2147483648, 2147483647, 20);
        div.p('\n');
        div.d(2147483647, -2147483648, 20);
        div.p('\n');
    }
}

이 방법은 기본적으로 우리 대부분이 학교에서 배운 것을 요청하여 소수 자릿수를 생성합니다.


공식 판결 : 무시하는 Integer.MIN_VALUE것은 좋지 않지만 long입력은 괜찮습니다.
durron597

훨씬 짧습니다. 잘 했어요
durron597

@ durron597 감사합니다. 여전히 엄격한 타이핑과 System.outJava가 부피가 커지는 느낌 ;-) 여전히 좋은 답변입니다. 이미 답변이 게시되어 있습니다.
생성자

1
@ durron597 당신은 특별히 계산하지 않기 위해 함수를 요청했습니다. 아마도 네보다 수입품을 사용해야한다면.
생성자

1
적어도 모든 변수에 대한 $는 없습니다 ;-)
TheConstructor

9

C, 98 95 89

d(a,b,c){if(a>0^b>0)a=-a,printf("-");for(printf("%d.",a/b);c--;putchar(a/b+48))a=a%b*10;}

c뒤에 숫자를 인쇄 합니다.

예제 출력 :

d(2,3,5);
0.66666

d(-2,3,5);
-0.66666

d(24352345,31412,500);
775.25611231376543995925124156373360499172290844263338851394371577740990704189481726728638736788488475741754743410161721635043932255189099707118298739335285878008404431427479943970457150133706863618999108620909206672609193938622182605373742518782630841716541449127721889723672481854068508850120972876607665860180822615560932127849229593785814338469374761237743537501591748376416656055010823888959633261174073602444925506175983700496625493441996689163377053355405577486310963962816757926906914554947153953

d(-77,12346463,500);
-0.00000623660395693892250760399962321192717298873369644407471192356871761572524859953818352673150196943043525906974329409159530142357369879940514137530724386409289850866600418273638369142644334656816288195250736992448768525852302801215214430238036593962173620088603513411087855687900251270343579371679160258286118056645048869461642577311412993340683886551152342172814999729072204727783171585254821563066280601982932277851559592411203111368818745903178910429650985873444078680671541315111866451144752954

-2147483647 <= a <= 2147483647에서 작동하며 b와 동일합니다. 처리는 -고통이었다.

온라인 버전 : ideone


이것이 -2147483648 인 경우 작동합니까? 어떤 정수 유형이 매개 변수에 할당되는지 알 수있을만큼 c 컴파일러를 잘 모릅니다.
생성자

지적 해 주셔서 감사합니다. -2147483647 <= a <= 2147483647에 대해 올바르게 작동하며 b와 동일합니다. a = -2147483648이고 b로 인해 양수인 경우 문제가 a=-a있습니다.
izabera

나는 시도했지만 결국 본질적으로 당신과 같은 해결책을 얻었습니다. 1을 printf("-")반환 하여 한 문자를 절약 할 수 있습니다 .
Thomas

4

PHP, 108

function d($a,$b,$c){$a*$b<0&&$a*=-print'-';for($p='.';$c--;$a.=0,print$i.$p,$p='')$a-=$b*$i=($a-$a%$b)/$b;}

단계 반복 중에 a/ 의 몫을 간단히 출력 하여 나머지를 각 반복마다 10으로 곱하여 작동합니다.bca

데모


a 또는 b가 음수
The Constructor

음수 버그를 수정했습니다. 감사!
Razvan

112 버전의 코드를 찾았습니다. 반환 값function d($a,$b,$c){if($a*$b<0)$a*=-print'-';for($p='.';$c--;$a*=10,$p=''){$a-=$b*$i=($a-$a%$b)/$b;echo$i.$p;}} 참조
TheConstructor

감사. 나는 심지어 당신의 버전을 업데이트하고 여분의 1 바이트를 이길 수있었습니다.
Razvan

2

파이썬 111

f=lambda a,b,c:'-'[a*b>=0:]+'%s'%reduce(lambda(d,r),c:(d%c*10,r+`d/c`+'.'[r!='':],),[abs(b)]*c,(abs(a),''))[-1]

이 솔루션은 명시된 규칙을 위반하지 않습니다.


2

C : 72 자

d(a,b,c){for(printf("%d.",a/b);c--;putchar((a=abs(a)%b*10)/abs(b)+48));}

그것은 거의 전적으로해야 할 일을합니다. 그러나 다른 응답의 일부는 여기에 불안정한 값을 제공하거나 실패하므로 d(-2147483648,b,c)d(a,-2147483648,c)-2147483648의 절대 값이 32 비트 워드에 대한 범위를 벗어나 있기 때문이다.


2

펄, 산술 없음, 274 바이트

이것은 유클리드의 부서로, 비정상적인 메모리를 소비 할 가능성이 높습니다. 부동 소수점 숫자에서 수학에 가장 가까운 것은 비트 연산을 사용하여 구문 분석하는 것입니다.

sub di{($v,$i,$d,$e)=(0,@_);($s,$c,$j)=$i=~s/-//g;$s^=$d=~s/-//g;
$i=~s/\.(\d+)/$j=$1,""/e;$d=~s/\.(\d+)/$c=$1,""/e;
$z=0.x+length($c|$j);$i.=$j|$z;$d.=$c|$z;
($e,$m,$z,$t)=(1.x$e,0.x$i,0.x$d,"-"x($s&1));
for(;$e;$t.="."x!$v,$v=chop$e){$t.=$m=~s/$z//g||0;$m="$m"x10}
print"$t\n"}

예 :

di(-355,113,238);
di(1.13,355,239);
di(27942,19175,239);
di(1,-90.09,238);
di("--10.0","----9.801",239);
di(".01",".200",239);

산출:

-3.141592920353982300884955752212389380530973451327433628318
584070796460176991150442477876106194690265486725663716814159
292035398230088495575221238938053097345132743362831858407079
646017699115044247787610619469026548672566371681415929203539

0.0031830985915492957746478873239436619718309859154929577464
788732394366197183098591549295774647887323943661971830985915
492957746478873239436619718309859154929577464788732394366197
183098591549295774647887323943661971830985915492957746478873

1.4572099087353324641460234680573663624511082138200782268578
878748370273794002607561929595827900912646675358539765319426
336375488917861799217731421121251629726205997392438070404172
099087353324641460234680573663624511082138200782268578878748

-0.011100011100011100011100011100011100011100011100011100011
100011100011100011100011100011100011100011100011100011100011
100011100011100011100011100011100011100011100011100011100011
100011100011100011100011100011100011100011100011100011100011

1.0203040506070809101112131415161718192021222324252627282930
313233343536373839404142434445464748495051525354555657585960
616263646566676869707172737475767778798081828384858687888990
919293949596979900010203040506070809101112131415161718192021

0.0500000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000

1

루비, 178

def d(a,b,c)
    n=(a<0)^(b<0)
    a=-a if n
    m=a/b-b/a
    l=m.to_s.size-1
    g=(a*10**(10+c)/b).to_s
    f=m<0?"."+"0"*(l-1)+g[0..c-l-1] : g[0..l]+"."+g[l+1..c-2]
    p n ? "-"+f : f
end

테스트를위한 온라인 버전 .

트릭은 곱하는 것입니다 결과는 부동 소수점 연산의 단지 정수 배수 인, 그래서 꽤 높은 번호. 그런 다음 결과 문자열의 올바른 위치에 점과 0을 삽입해야합니다.


c보다 350보다 큰 값으로 작동합니까?
durron597

내가 = 1000 C와 함께 테스트 - 코드는 어쩌면 내가 ...하지만 실제 결과를 확인해야합니다, 나에게 대답을했다
데이비드 헤르만

2
않는 g큰 64 비트 이상의 얻을 c? 편집 : 나는 당신이 BigInteger여기에서 암시 적으로 사용하고 있다고 생각합니다
durron597

Err g은 문자열이지만 전화하기 전에 to_s크기가 64 비트를 초과하는 메모리에 숫자를 만들었습니다.
durron597

1
그것은 이해할 수 있으며 과제를 더 도전적이고 흥미롭게 만듭니다! 답변을 삭제하거나 다른 사람이 작업을 구현하지 않는 방법에 대한 예를 남기도록하는 것이 더 낫습니까?
David Herrmann

1

파이썬 92 바이트 :

def d(a,b,c):c-=len(str(a/b))+1;e=10**c;a*=e;a/=b;a=str(a);x=len(a)-c;return a[:x]+'.'+a[x:]

나는 더 많은 골프가 가능하다고 생각합니다 .....


2
않는 e대형 컴퓨터 용 64 비트 이상의거야? 편집 : 나는 당신이 BigInteger여기에서 암시 적으로 사용하고 있다고 생각합니다 .
durron597

1
@ durron597 나는 그것을 의심합니다. BigInt (python에서 길게)로 이동하지만 2 ** 45는 48 비트입니다. 충분한 명예인가요? 또한, 파이썬에는 프리미티브가 없습니다.
Maltysen

만약 a=5c=400다음 시간 이후 e=10**c, 진수의 숫자는 333 자리입니다. 그것은 시작 8889e7dd7f43fc2f7900bc2eac756d1c4927a5b8e56bbcfc97d39bac6936e648180f47d1396bc905a47cc481617c7...이 64 개를 초과하는 비트이다.
durron597

@ durron597 400 ... 내가 그것을해야합니까
Maltysen

1
그렇습니다. 규칙 3은 최대 500 명까지 지원해야한다고 말합니다.
durron597

1

C 83

d(a,b,c){printf("%d.",a/b);for(a=abs(a),b=abs(b);c--&&(a=a%b*10);)putchar(a/b+48);}

파이썬 구현에서 사용한 것과 동일한 아이디어


아주 좋아요! 그러나 그것은 충돌합니다d(-2147483648,-1,10)
durron597
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.