例如,参加此IRB会议:
1.9.3-p385 :046 > float = func_that_creates_large_float
=> 1.5815450433041317e+51
1.9.3-p385 :047 > float.to_i
=> 1581545043304131697954259018410479150921451567054848
我可以确定返回给我的整数表示与浮点数相同的值吗?我问主要是因为Ruby文档将Float类中的to_i
方法描述为“返回将截断为整数的浮点数”。 “截断”这个词突然出现在我身上。
编辑:我认为描述我的情况会清楚说明我为什么要问这个问题。我试图取一个大整数的立方根,我知道它也会产生一个整数。立方根函数使用浮点数进行计算,将结果作为浮点数给出。我需要非科学符号值,不知道如何处理这个问题。
谢谢。
答案 0 :(得分:1)
相反,(确定性但无意义的)数据已添加(如您在代码示例中所示)。您没有丢失任何信息。但它的价值并不相同。
您的float
精度约为17位小数,您的int
突然精确到51位数。这与Floating Point Arithmetic: Issues and Limitations有关。那"精度"由于十进制浮点值的二进制表示而产生,这导致了"发明"整数中的一系列数字。
考虑以下内容(在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
module将是一个很好的妥协:
>>> 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')
(由于将1/3
表示为十进制浮点数的问题仍然存在轻微的舍入错误,但结果很明显,不是吗?)
答案 1 :(得分:1)
显然,如果有效数字的数量大于指数部分的数量,那么在浮动到整数转换期间,您将丢失信息。
Ruby(与许多其他编程语言一样)没有可变精度浮点。相反,有效数字的数量固定为常数Float::DIG
,默认为15。这意味着,如果浮点数小于10 ^ 15,那么在浮点数到整数转换期间,您将丢失信息。
<小时/> 关于整数中立方根的问题,最好在
Rational
类中进行计算。您不必担心截断。
(8 ** Rational("1/3")).to_r
# => (2/1)