3

如何在红宝石中将 9999999999999999999999.001 转换为“9999999999999999999999.001”

我试过了

>> 9999999999999999999999.001.to_s
=> "1.0e+22"

>> "%f" % 9999999999999999999999.001
=> "10000000000000000000000.000000"
4

3 回答 3

2

事实是你不能。你写的数字是 22 位,而 ruby​​ 中的浮点数只有 15 位精度。所以当你使用这个变量时,它的一部分值已经像 Float 类一样“丢失”了。

于 2013-01-12T11:05:23.663 回答
2

BigDecimal从标准库中使用。

1.8.7 :005 > require 'bigdecimal'
 => true 
1.8.7 :006 > BigDecimal('9999999999999999999999.001')
 => #<BigDecimal:7fe0cbcead70,'0.9999999999 9999999999 99001E22',36(36)> 
1.8.7 :007 > BigDecimal('9999999999999999999999.001').to_s
 => "0.9999999999999999999999001E22"

当然,这个例子只是说明 BigDecimal 可以处理那么大的数字。无论您最初是从哪里获取您的9999999999999999999999.001号码,都需要在BigDecimal计算/输入后立即将其输入。

于 2013-01-12T11:10:22.290 回答
1

你不能这样做。原因很简单:从一开始,数字的值就不会是9999999999999999999999.001. 浮点数只有 15 位精度。

但是,您可以使用其他类型来实现您想要的:

require 'bigdecimal'
a = BigDecimal("9999999999999999999999.001")
a.to_s("F")
>> "9999999999999999999999.001"

因为BigDecimal精度随着更大实数的要求而扩展 - 没有应用限制。

Float的计算速度更快,因为它意味着直接使用处理器的FPU,但也因此受到了精度的限制。

编辑特别是对于@izomorphius 和他的论点,只是一个非常短的代码示例:

a = "34.101"
b = BigDecimal(a.to_s)
c = b ** 15
c.to_s("F")
>>> 98063348952510709441484.183684987951811295085234607613193907150561501

现在告诉我如何获得最后一个字符串?

于 2013-01-12T11:16:38.257 回答