任意精度の除算を実装する


15

divide(int a, int b, int c)のベース10値を出力する関数を実装しますa/b。浮動小数点演算もBigInteger/ BigDecimalまたは同等のライブラリも一切使用しません。以下の4の(可能性のある)例外を除きc、のセット内の少なくとも正確な文字を0123456789.印刷する必要があります。

  1. aそしてb、任意の32ビットの整数であってもよいです。更新:ゴルフの目的で、入力に問題のない64ビットプリミティブを使用する場合は、64ビット範囲のデータ全体をサポートする必要はありません。
  2. そうでない場合は、それcが正であることを確認する必要はありません(ただし、プログラムがクラッシュしないことを願っています)。
  3. のサポートされる最小の上限c500です。プログラムがc上記の値をサポートしていない場合でも問題ありませんが、サポート500している場合でも問題ありません。
  4. 数値が均等に分割される場合、余分なゼロを(の値に基づいて)印刷するかc、何も印刷しないかを選択できます。
  5. この関数を使用して商でさらにタスクを実行する必要はありません。唯一の目標は印刷です。
  6. -1との間の数値について1は、先頭を印刷するかどうかを選択します0。ただし、これは先行ゼロの印刷が許容される唯一のシナリオであり、このようなゼロを1つだけ印刷できます。
  7. 最後の小数位には、任意の丸め/フロア/セルロジックを使用できます。
  8. 否定的な答えを得るには、先頭に-。を印刷する必要があります。これはにカウントされませんc。しかし、それはあなたが印刷したい場合はあなたの選択ではない+または肯定的な回答のために何も。
  9. 整数除算と整数モジュラスの両方が許可されます。ただし、コードの長さに対してカウントされる独自のBigInteger/ BigDecimalライブラリを実装することを選択しない限り、プリミティブに制限されることに注意してください。
  10. あなたが処理する必要がありませんbという0ことができますけれども、あなたがしたい場合は、。プログラムが無限ループに入るか、ifがクラッシュすると、b=0ペナルティは科せられません。
  11. コメントごとにわずかなルール変更。競技場が水平でありab32ビット整数であることが保証されるようにするには、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)一部の言語の大きな数の型プリミティブです。
ジョナサンヴァンマトレ14

@JonathanVanMatreコメントごとにルール11を追加
durron597 14

1
正確な数字をどのように数えますか?あなたの例では、最後の引数が示すように、3つまたは4つを見ますが、5つを見ることはありません。
ハワード14

@Howardは、あなたがやった場合92,3,5の答えは、例えば、だろう、30.67
durron597

1
btw 370/3 = 123.333 lol
izabera 14

回答:


5

Java、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);}

正の32ビット整数は2147483647にのみカウントされるため、-2147483648になるように即興で演奏するa必要bがありaましたlong。否定的な結果を処理するためのより良い方法があるかもしれませんが、私は何も知らない(doublesはおそらく彼らが持っているようにこれを機能させるでしょうが、1の補数のみが精度を維持します)。abs(a) < abs(b)-0

なぜ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');
    }
}

このメソッドは、基本的に学校で学んだことのほとんどを実行して、要求された10進数を生成します。


公式の裁定:無視することInteger.MIN_VALUEは大丈夫ではないが、longインプットとしては大丈夫だと思う。
durron597 14

それはずっと短いです。よくできました。
durron597 14

@ durron597ありがとう。まだ厳密なタイピングとSystem.outJavaをかさばる気分にさせる;-)まだいい感じです。すでに長い回答が投稿されています。
TheConstructor 14

1
@ durron597あなたは具体的に関数を要求したので、私はそれがカウントされないだろうと思った。おそらくはいよりもインポートを使用しなければならなかった場合。
TheConstructor 14

1
少なくとも、すべての変数に$はありません;-)
TheConstructor 14

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コンパイラを知らない。
TheConstructor 14

指摘してくれてありがとう。-2147483647 <= a <= 2147483647で正常に動作し、bでも同じです。a = -2147483648でbが正の場合に問題が発生しa=-aます。
izabera 14

私は試しましたが、最終的にあなたと本質的に同じ解決策を得ました。あなたは実現することにより、一つの文字を保存することができますprintf("-")戻って1
トーマス

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

デモ


またはbが負の場合奇妙な結果を生成します
TheConstructor

負の数のバグを修正しました。ありがとう!
ラズバン14

ちょうどあなたのコードの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バイト余分に勝ちました。
ラズバン14

2

Python 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

Perl、算術演算なし、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

テスト用のオンラインバージョン

トリックは、aをかなり大きな数で乗算することであるため、結果は浮動小数点演算の整数倍になります。次に、結果の文字列の適切な場所にポイントとゼロを挿入する必要があります。


これは350より大きいcで動作しますか?
durron597 14

多分私はかかわらず、実際の結果をチェックする必要があり、コードは私に答えを与えた... -私は、c = 1000でそれをテストした
デビッド・ヘルマン

2
ないg大規模のための64ビットを超えて取得しますかc?編集:私はあなたが暗黙的に使用していると思うBigIntegerここに
durron597

errは、g文字列ですが、あなたは呼び出す前にto_s、あなたのサイズが64ビットを超えているメモリ内の数作成しました
durron597

1
それは理解できます-そして、タスクをより挑戦的(そして興味深い)にします!答えを削除するか、タスクを実装しない方法の例を示すために他の人に残しておく方が良いでしょうか?
デビッド・ハーマン14

1

python 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大規模なCのための64ビットを超えて取得しますか?編集:BigIntegerここで暗黙的に使用していると思います。
durron597 14

1
@ durron597私はそれを非常に疑います。BigInt(PythonではLong)になりますが、2 ** 45は48ビットです。それで十分な予言ですか?? また、Pythonは...ので、NOプリミティブを持っている
Maltysen

場合a=5c=400、その後の後e=10**c、進では、数は333桁の長さ。それは始まり8889e7dd7f43fc2f7900bc2eac756d1c4927a5b8e56bbcfc97d39bac6936e648180f47d1396bc905a47cc481617c7...、これは64ビット以上です。
durron597 14

@ durron597 400 ...それが必要ですか
マルティセン14

1
はい、ルール3には、少なくとも500までサポートする必要があると書かれています。
durron597 14

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);}

私のPython実装で使用したのと同じアイデア


非常に素晴らしい!ただし、クラッシュしますd(-2147483648,-1,10)
durron597 14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.