浮動小数点数を10進数として正確にフォーマットする


9

2進浮動小数点は、10進数で正確にフォーマットできます。結果の文字列は多少長くなる可能性がありますが、可能です。では、浮動小数点の私の記事私は精度の重要性をカバーし、そして今、私はこの機能が欲しいです。この課題は、浮動小数点値を入力として受け取り、正確な10進文字列を出力としてフォーマットするプログラムまたは関数を記述することです。

正しい浮動小数点数で作業していることを確認するには、プログラムへの入力として正確な形式を指定する必要があります。この形式は2つの整数Significand Exponentで、実際の浮動小数点値はSignificand * 2 ^ Exponentです。どちらの値も負になる可能性があることに注意してください。

詳細:

  • 少なくとも32ビットfloatの範囲と精度をサポートする必要があります(それ以上の入力はできません)
  • 10進数でフォーマットされた値は正確な表現である必要があります(浮動小数点への正しい丸めを保証するのに十分近いだけでは十分ではありません)。
  • 標準ライブラリの浮動小数点フォーマット関数の正確性や十分な速さ(例:)を信頼していないprintfため、使用できない場合があります。あなたは、書式設定を行う必要があります。統合フォーマット/変換関数が許可されています。
  • .整数コンポーネントがない場合は、の前に必要な1つの先行ゼロを除いて、先行ゼロまたは後続ゼロがない場合があります。
  • 関数、またはプログラム全体が許可されます。

例:

1 -2 => 0.25
17 -3 => 2.125
-123 11 => -251904
17 50 => 19140298416324608
23 -13 => 0.0028076171875
3 120 => 3987683987354747618711421180841033728
3 -50 => 0.00000000000000266453525910037569701671600341796875
-3 -50 => -0.00000000000000266453525910037569701671600341796875
10 -2 => 2.5
-12345 -3 => -1543.125
0 0 => 0
161 -4 => 10.0625
512 -3 => 64

最短のコードが勝ちます。


3
無制限の精度の浮動小数点演算を使用できますか?
デニス

2
指数が負でない場合、最後にでき.0ますか?
Sp3000

@Dennis:はい、無制限または高固定精度の演算が許可されています。
edA-qa mort-ora-y 2015

1
それは矛盾していると思います。0.abcが先行ゼロでない場合はabc.0、後続ゼロではありません。
orlp 2015

1
また.0、浮動小数点数を処理するときは常に整数で終わるのも慣例です。たとえば、Python:str(1.0) == '1.0'とを参照してくださいstr(1) == '1'。あなたの論理はまだ一貫していません。
orlp 2015

回答:


3

CJamさん、43歳

r_'-&\ize999rim<s1e3'0e[W%999/(i_L?\+'.*sW%

オンラインでお試しください

説明:

このプログラムは、倍精度(64ビット)に近い±999までの指数で動作します。マイナス記号(存在する場合)を仮数から分離し、10 999を乗算します。次に、指数を使用してビットシフトを実行します。これは、正確な計算です。次に、結果が1000桁未満の場合は左側にゼロを埋め込み、最後の999桁を小数部として分離し、その逆を整数に変換して末尾のゼロを削除し、必要に応じて小数点を追加して、すべてを元に戻します。

r_         read and duplicate the significand in string form
'-&        keep only the minus sign, if present
\          swap with the other copy of the significand
iz         convert to integer and get absolute value
e999       multiply by 10^999
ri         read the exponent and convert to integer
m<         shift left by it; negative values will shift right
            the result is an exact non-negative integer
s          convert to string
1e3'0e[    pad to the left with zero characters up to length 1000
            longer strings will be left intact
            we need 1 more than 999 for the 0.xxx case
W%         reverse the string
999/       split into slices of length 999
(          take out the first slice (reversed fractional part)
i          convert to integer
            this removes the leading zeros (trailing in reverse)
_L?        if it's zero, replace with an empty string
\+         concatenate back (to the left) with the second slice
'.*        join the with the dot character
            if the fractional part was zero, we only have the second slice
            (reversed integer part) and there is nothing to join
s          convert to string; this is the reversed result without the sign
W%         reverse back

最後に、マイナス記号(存在する場合)と最終文字列が自動的に一緒に印刷されます。


2

CJam、50バイト

q~A1$z#\_0>K5?\z:E#@_s'-&oz*\md_sE'0e[W%isW%'.\+Q?

これは、STDINから読み取る完全なプログラムです。CJamインタープリターでオンラインで試してください。

すべてのテストケースを一度に確認します。


あなたのコメントに基づいて、私はCJamが無制限の精度を持っていると思います、そしてあなたはここでそれを使いましたか?この答えは、32ビットの浮動小数点数だけでなく、あらゆる入力をカバーすることは正しいですか?また、それがどのように機能するかの説明を得ることができますか?
edA-qa mort-ora-y 2015

CJamの整数の精度は無制限ですが、倍精度の浮動小数点数のみです。正の指数の場合は20の累乗、負の指数の場合は5の累乗を掛けて、ストリングにキャストしてドットを挿入します。数時間後に詳細な説明を追加します。
デニス

そして、はい、十分なメモリがあれば、これはどの入力でも機能するはずです。
デニス

10 -2末尾ゼロ持っていると思わ
SEは悪であるためaditsuが終了

@aditsu:ああそう、2の累乗ごとに1つの後続ゼロ...
デニス

2

GNU sed + dc、65

スコアには、sedの-rオプションの+1が含まれます。

y/-/_/
s/.*/dc -e"C8k& 2r^*p"/e
s/\\\n//
s/0+$//
s/^(-?)\./\10./

私はこれをdc唯一の答えC8k& 2r^*pとして10のスコアで主張したくなりましたdcが、いくつかのフォーマットの癖があります:

  • -ve記号の_代わりに-
  • 長い行はバックスラッシュで壊れています
  • 末尾のゼロは削除する必要があります
  • 先頭に0を|n| < 1追加する必要があります

したがって、DC式はsed、上記を処理するためにラップされ、評価されます。

テスト出力:

$ echo "1 -2
17 -3
-123 11
17 50
23 -13
3 120
3 -50
-3 -50
8388608 127
1 -127" | sed -rf float.sed
0.25
2.125
-251904
19140298416324608
0.0028076171875
3987683987354747618711421180841033728
0.00000000000000266453525910037569701671600341796875
-0.00000000000000266453525910037569701671600341796875
1427247692705959881058285969449495136382746624
0.0000000000000000000000000000000000000058774717541114375398436826861112283890933277838604376075437585313920862972736358642578125
$ 

うーん、dc標準のフォーマット関数の使用に関する私のルールに違反していると思います。
edA-qa mort-ora-y 2015

1
@ edA-qamort-ora-y 「無制限または高い固定精度の演算が許可されている」ことをdc考えると、の使用は問題ないと考えました。 のコマンドは「浮動小数点フォーマット関数」ではありません-任意精度の印刷関数です。精度を小数点以下128桁()に設定しています。これは、32ビットの浮動小数点には十分すぎると思います。dcpC8k
デジタルトラウマ2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.