Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 如何防止BigDecimal截断结果?_Ruby_Precision_Bigdecimal - Fatal编程技术网

Ruby 如何防止BigDecimal截断结果?

Ruby 如何防止BigDecimal截断结果?,ruby,precision,bigdecimal,Ruby,Precision,Bigdecimal,后续行动: 我想计算1/1048576并得到正确的结果,即0.00000095367431640625 使用BigDecimal的/截断结果: require 'bigdecimal' a = BigDecimal.new(1) #=> #<BigDecimal:7fd8f18aaf80,'0.1E1',9(27)> b = BigDecimal.new(2**20) #=> #<BigDecimal:7fd8f189ed20,'0.1048576E7',9(27)

后续行动:

我想计算1/1048576并得到正确的结果,即0.00000095367431640625

使用
BigDecimal
/
截断结果:

require 'bigdecimal'
a = BigDecimal.new(1)
#=> #<BigDecimal:7fd8f18aaf80,'0.1E1',9(27)>
b = BigDecimal.new(2**20)
#=> #<BigDecimal:7fd8f189ed20,'0.1048576E7',9(27)>

n = a / b
#=> #<BigDecimal:7fd8f0898750,'0.9536743164 06E-6',18(36)>

n.to_s('F')
#=> "0.000000953674316406" <- should be ...625
但我真的不明白这个精确的论点。为什么我必须指定它?我必须使用什么值来获得未截断的结果

这是否符合“任意精度浮点十进制算术”

此外,如果我通过以下方式计算上述值:

a = BigDecimal.new(5**20)
#=> #<BigDecimal:7fd8f20ab7e8,'0.9536743164 0625E14',18(27)>
b = BigDecimal.new(10**20)
#=> #<BigDecimal:7fd8f2925ab8,'0.1E21',9(36)>

n = a / b
#=> #<BigDecimal:7fd8f4866148,'0.9536743164 0625E-6',27(54)>

n.to_s('F')
#=> "0.00000095367431640625"
a=BigDecimal.new(5**20)
#=> #
b=大十进制。新(10**20)
#=> #
n=a/b
#=> #
n、 至_s(‘F’)
#=> "0.00000095367431640625"

我确实得到了正确的结果。为什么?

BigDecimal可以执行任意精度的浮点十进制算法,但不能自动确定给定计算的“正确”精度

例如,考虑

BigDecimal.new(1)/BigDecimal.new(3)
# <BigDecimal:1cfd748, '0.3333333333 33333333E0', 18(36)>
对于任何小于10的值,BigDecimal会将结果截断为9位,这就是为什么在精度为10时,精度会突然提高:在这一点上,将切换为截断为18位(然后四舍五入为10位有效数字)



†取决于您比较可数无限集大小的舒适程度。

类似于
(1.0/3)。是真的吗?(Float)#=>是真的吗?
BigDecimal.new(1)/BigDecimal.new(3)
可以写成
BigDecimal.new(1)/3
(BigDecimal.new(1)/3)。是真的吗?(BigDecimal)#=>甚至是
BigDecimal.new(1)/Rational(3)
n.to_s('F')
返回的精度比
n
更高,这一事实表明
BigDecimal
对象包含的内容超出了人们的想象。你是否愿意花周末的时间钻研
BigDecimal
?一个开始的地方可能是。顺便说一句,你能解释一下
(BigDecimal.new(1)/3).finite吗?#=>true
?@CarySwoveland“
n.to_s('F')
返回的精度比
n
更高”-你是什么意思?@CarySwoveland“你能解释
(bigdecimic.new(1)/3).有限吗?=>true
?”–根据,我的意思是
n=a/b
返回10位有效数字,而
n.to\s
返回12位有效数字。请忘记我提到的
finite
。解释我脑子里到底在胡说八道,需要花太多的话,这将是一件非常无聊的事情。这就解释了为什么我可能需要为某些计算指定一个精度(尽管我的例子有一个有限的结果)。但它并没有真正解释“我必须使用什么值才能得到未截断的结果”部分。例如,为什么12到18个返回相同的结果,而19个突然返回两个以上的数字?此外,如果我使用5^20/10^20而不是1/2^20来计算结果,即
BigDecimal.new(5**20)/BigDecimal.new(10**20)
,我会得到正确的结果。你能解释一下吗?@Stefan说实话,我不完全理解精确性参数是如何工作的。但对于您的特定示例,除以10的任何幂总能得到准确的结果,因为大小数存储为整数乘以10的幂。
BigDecimal.new(1)/BigDecimal.new(3)
# <BigDecimal:1cfd748, '0.3333333333 33333333E0', 18(36)>
1   0.000001
2   0.00000095
3   0.000000953
9   0.000000953
10  0.0000009536743164
11  0.00000095367431641
12  0.000000953674316406
18  0.000000953674316406
19  0.00000095367431640625