Ruby on rails Ruby在23+;9.23 = 32.230000000000004

Ruby on rails Ruby在23+;9.23 = 32.230000000000004,ruby-on-rails,ruby,Ruby On Rails,Ruby,在Ruby的irb中,我收到了非常有趣而且似乎不稳定的结果。发生了什么事 puts "%.30f" % 9.23 #=> 9.230000000000000426325641456060 这是正确的 >> 23+9.22 => 32.22 这不是 >> 23+9.23 => 32.230000000000004 所有尾随的零从哪里来?发生了什么事 puts "%.30f" % 9.23 #=> 9.23000000000000042632

在Ruby的irb中,我收到了非常有趣而且似乎不稳定的结果。发生了什么事

puts "%.30f" % 9.23
#=> 9.230000000000000426325641456060
这是正确的

>> 23+9.22 
=> 32.22
这不是

>> 23+9.23 
=> 32.230000000000004
所有尾随的零从哪里来?发生了什么事

puts "%.30f" % 9.23
#=> 9.230000000000000426325641456060
由于base-2(计算机内部数字表示)和base-10(您习惯于处理并正在文本编辑器或IRB中键入的内容)之间的差异,您无法将9.23精确地表示为浮点值。这不是Ruby特有的,但几乎存在于每种编程语言中

例如,9.23在内部表示为2的幂和,类似于:

01001.00111010111。。。
||||| ||||||||||+-> 1 * 1/2048 \            
||||| |||||||||+--> 1 * 1/1024  \          
||||| ||||||||+---> 1 * 1/512    \        
||||| |||||||+----> 0 * 1/256     \       
||||| ||||||+-----> 1 * 1/128      \      
|||||||||+------>0*1/64分数=0.22998046875
||||| ||||+-------> 1 * 1/32       /     
||||| |||+--------> 1 * 1/16      /      
||||| ||+---------> 1 * 1/8      /      
||||| |+----------> 0 * 1/4     /       
||||| +-----------> 0 * 1/2    /        
|||||  
||||+-------------> 1 * 1      \
|||+--------------> 0 * 2       \  
||+--------------->0*4整数=9
|+----------------> 1 * 8       /
+-----------------> 0 * 16     /
有关更多信息,请阅读和阅读

当精度很重要(如货币)时,您的解决办法是:

  • 记录可用于计算的最小单位(如便士),仅转换为十进制显示。例如:

    result=2300+923#$23.00+9.23
    将“%.2f”%(结果/100.0)#确保输出四舍五入到小数点后两位
    #=> 32.23
    
  • 使用库(如)跟踪精确精度,并将数据库设置为使用固定精度数据类型(如)

  • 接受数字值通常“足够接近”,并在向用户显示它们时始终使用格式选项,例如:

    result=23+9.27#=>32.26999996
    将“%g”%result#=>32.27
    将“%.3f%”结果#=>32.270
    将“%.1f%”结果#=>32.3
    

  • 这不是Ruby的问题。这是计算机中浮点数表示的一个已知问题


    如果你在做财务或货币处理,那么你就不要用浮点数来表示你的金额。

    这就是处理浮点数的方法。这在Python中是一样的,在大多数语言中也是一样的。看到了吗,我想这是一个长期以来最受欢迎的话题已经有一段时间了。关于这个问题,以前已经问过很多次了。事实上,有一个网站专门回答这个问题:只要有人使用WECSSKAFPA的链接,就应该有一顶帽子。我个人曾向人们指出过大约100次。我可以用摩尔哈兹。