浮点数格式没有在ruby中舍入

Nod*_*rov 4 ruby format floating-point

有一个浮点数num = 22.0098.如何将其格式化为浮点后限制3位数?我试过sprintf('%.3f',num),但回报是22.010,我需要的22.009不过

shi*_*vam 7

我可以想到使用bigdecimal.不确定,如果它是一个矫枉过正:

require 'bigdecimal'   
BigDecimal::new("22.0098").truncate(3).to_f
#=> 22.009
Run Code Online (Sandbox Code Playgroud)

  • @NodirNasirov它不是第三方宝石.[`BigDecimal`](http://ruby-doc.org/stdlib-1.9.3/libdoc/bigdecimal/rdoc/BigDecimal.html)是Ruby内置支持. (4认同)

Ale*_*kin 4

不幸的是,与 不同的是Float#roundFloat#floor它不接受一定数量的数字。下面的代码实现了所需的行为。

\n\n
def floor_float input, digits = 3\n  input.divmod(10 ** -digits).first / (10 ** digits).to_f  \nend \n
Run Code Online (Sandbox Code Playgroud)\n\n

这可以用作猴子补丁:

\n\n
class Float\n  def floor_ext digits = 3\n    self.divmod(10 ** -digits).first / (10 ** digits).to_f  \n  end \nend\n22.0098.floor_ext\n#\xe2\x87\x92 22.009\n
Run Code Online (Sandbox Code Playgroud)\n\n

正如@Stefan 所建议的,可能是更简洁的变体:

\n\n
class Float\n  def floor_ext digits = 3\n    div(10 ** -digits).fdiv(10 ** digits)\n  end \nend\n22.0098.floor_ext\n#\xe2\x87\x92 22.009\n
Run Code Online (Sandbox Code Playgroud)\n\n

或者,可以明确地处理字符串:

\n\n
i, f = 22.0098.to_s.split(\'.\')\n#\xe2\x87\x92 [ "22", "0098" ]\n[i, f[0..2]].join(\'.\')\n#\xe2\x87\x92 "22.009"\n
Run Code Online (Sandbox Code Playgroud)\n