0

たとえば、次の IRB セッションを見てください。

1.9.3-p385 :046 > float = func_that_creates_large_float
=> 1.5815450433041317e+51 
1.9.3-p385 :047 > float.to_i
=> 1581545043304131697954259018410479150921451567054848

返された整数が float と同じ値を表していることを確認できますか? 主な理由は、Ruby のドキュメントto_iで Float クラスのメソッドが「整数に切り捨てられた float を返す」と説明されているためです。「切り詰められた」という言葉が飛び出します。

編集:私の状況を説明すると、なぜ私がこれを求めているのかが明確になると思います. 整数になることがわかっている大きな整数の立方根をとろうとしています。立方根関数は float を使用して計算を行い、結果を float として返します。非科学的表記法の値が必要ですが、これにアプローチする方法がわかりません。

ありがとうございました。

4

2 に答える 2

1

逆に、(決定論的だが無意味な)データが追加されます(コードサンプルで示したように)。情報を失うことはありません。しかし、それは同じ値ではありません。

あなたfloatの精度は 10 進数で約 17 桁ですが、int突然 51 桁の精度になります。これはFloating Point Arithmetic: Issues and Limitationsに関係しています。その「精度」は、10 進浮動小数点値のバイナリ表現の結果として発生し、整数の一連の数字の「発明」につながります。

次のことを考慮してください (Python では、任意の長整数を特徴とするすべてのプログラミング言語と同様に、同じ規則に従います)。

>>> a = int(1.5815450433041317e+51)
>>> a
1581545043304131697954259018410479150921451567054848
>>> b = a + 10000000000000000
>>> a == b
False
>>> float(a) == float(b)
True
>>> a == 1.5815450433041317e+51
True

Python では、decimalモジュールは非常に良い妥協点になります。

>>> from decimal import Decimal, getcontext
>>> a = str(29873409852730498572309485723**3)  # just an arbitrary number
>>> getcontext().prec = 100
>>> cube = Decimal(a)
>>> cube ** Decimal("0.333333333333333333333333333333333333333333333333333333333
33333333333333333333")
Decimal('29873409852730498572309485722.99999999999999999999999999999999999999999
999998041297117811390088120595')

(10 進浮動小数点として表現する問題により、まだわずかな丸め誤差があります1/3が、結果は明らかですよね?)

于 2013-08-03T21:10:08.973 に答える
1

明らかに、有効数字の数が指数部分の大きさよりも大きい場合、浮動小数点から整数への変換中に情報が失われます。

Ruby (他の多くのプログラミング言語と同様) には、可変精度浮動小数点がありません。代わりに、有効数字の数は定数Float::DIGに固定されており、既定では 15 です。つまり、float が 10^15 より小さい場合、float から整数への変換中に情報が失われます。


整数内の立方根に関する質問については、Rationalクラス内で計算を行う方がよいでしょう。切り捨てについて心配する必要はありません。

(8 ** Rational("1/3")).to_r
# => (2/1)
于 2013-08-03T21:10:16.717 に答える