【问题标题】:How do you round a float to 2 decimal places in JRuby?如何在 JRuby 中将浮点数舍入到小数点后 2 位?
【发布时间】:2020-10-23 18:31:57
【问题描述】:

如何在 JRuby(1.6.x) 中将浮点数四舍五入到小数点后 2 位?

number = 1.1164
number.round(2)

# The above shows the following error
# wrong number of arguments (1 for 0)

【问题讨论】:

    标签: ruby jruby rounding


    【解决方案1】:
    (5.65235534).round(2)
    #=> 5.65
    

    【讨论】:

    • (5.6).round(2) 仅返回 5.6
    • 似乎是合理的,额外的零占位符仍然存在,只是不可见
    • @BalaKarthik 这就是我使用 Theo 解决方案的原因。它会正确舍入(除非您出于某种奇怪的原因超过 3 位小数,请参阅 cmets),因此如果您正在寻找字符串输出,这是更好的解决方案。
    • 这是对的。我是生成随机纬度和经度,所以我使用 number.round(6) 6 位数
    【解决方案2】:

    sprintf('%.2f', number) 是一种神秘但非常强大的数字格式化方式。结果始终是一个字符串,但是由于您正在四舍五入,我假设您这样做是为了演示目的。 sprintf 几乎可以以任何你喜欢的方式格式化任何数字,还有更多。

    完整的 sprintf 文档:http://www.ruby-doc.org/core-2.0.0/Kernel.html#method-i-sprintf

    【讨论】:

    • '%.2f' % number 也更常见,至少在我的经验中是这样。
    • @MichaelKohl ruby style guide 优于 % 版本的 sprintf(或 format)。 here 讨论了一些原因,主要是关于可读性。并不是说我们都必须遵循样式指南,只是给出一些理由:)
    • 请注意,在小数点后 3 位之后,sprintf 会向上取整 6,而不是 5,例如,sprintf("%.3f", 1.2225) 将是 "1.222", sprintf("%.3f ", 1.2226) 将是 "1.223",如果这对您很重要,请坚持使用#round
    • "%.2f" 轮到 5 向下而不是向上,有什么办法可以解决这个问题吗?
    • @ricks 浮点数是二进制的,而不是十进制的。在不改变二进制表示的情况下,无法四舍五入到特定的小数位数。在许多数据库中使用类似 DECIMAL 类型的东西,但最常见的四舍五入原因是为了表示,所以使用字符串并不是不合理的。如果由于会计规则而四舍五入,则应以十进制表示而不是浮点数开头。
    【解决方案3】:

    Float#round 可以在 Ruby 1.9 中使用参数,而不是在 Ruby 1.8 中。 JRuby 默认为 1.8,但它支持running in 1.9 mode

    【讨论】:

    • 我知道 Sam 似乎无意将数字四舍五入以呈现货币之类的东西,但请注意,如果出现以下情况,使用 #round(precision) 将无法按预期工作您正在尝试执行此操作(3.round(2) #=> 3.0,而不是 3.00)。要得到这个,请查看下面 Theo 的答案。
    【解决方案4】:

    编辑

    得到反馈后,原来的解决方案似乎不起作用。这就是为什么将答案更新为建议之一。

    def float_of_2_decimal(float_n) 
      float_n.to_d.round(2, :truncate).to_f
    end
    

    如果您希望获得小数点后 2 位的四舍五入数字,其他答案可能会起作用。但是,如果您想获得前两位小数的浮点数不四舍五入,那么这些答案将无济于事。

    所以,为了获得前两位小数的浮点数,我使用了这种技术。 在某些情况下不起作用

    def float_of_2_decimal(float_n)
      float_n.round(3).to_s[0..3].to_f
    end
    

    使用5.666666666666666666666666,它将返回5.66,而不是四舍五入的5.67。希望它会帮助某人

    【讨论】:

    • 这不起作用。为了让它工作,你需要考虑任何尺寸。使用此处实现的模式,您可以:def float_of_2_decimal(float_n) num = float_n.to_s.split('.') num[1] = num[1][0..1] num.join(".").to_f end 或者更简单,您可以使用 float_n.to_d.round(2, :truncate).to_f
    • 小数点前 int 大于 9 的任何东西
    • 谢谢你的意见。但是,您建议的方法在大数字上也失败了!
    • 是的,你是对的......曾经超过 16 个位置。溢出问题。如果使用大数,最好坚持使用大小数。类型转换引入问题
    • @rorykoehler 我尝试了你的方法并得到:'111111111111111111111111.222222'.to_d.round(2, :truncate).to_f 返回1.1111111111111111e+23。但是,如果您删除最后一个 .to_f,它会起作用
    【解决方案5】:

    试试这个:

    module Util
    module MyUtil
    
    
    
        def self.redondear_up(suma,cantidad, decimales=0)
    
            unless suma.present?
                return nil
            end
    
    
            if suma>0
                resultado= (suma.to_f/cantidad)
                return resultado.round(decimales)
            end
    
    
            return nil
    
    
        end
    
    end 
    end 
    

    【讨论】:

    • 感谢您的回答。您能否将其修改为英文,因为问题是用英文提出的。
    【解决方案6】:

    为了截断小数,我使用了以下代码:

    <th><%#= sprintf("%0.01f",prom/total) %><!--1dec,aprox-->
        <% if prom == 0 or total == 0 %>
            N.E.
        <% else %>
            <%= Integer((prom/total).to_d*10)*0.1 %><!--1decimal,truncado-->
        <% end %>
            <%#= prom/total %>
    </th>
    

    如果你想截断到 2 位小数,你应该使用Integr(a*100)*0.01

    【讨论】:

    • 在投射百分比时,任何人都不应该这样做。这是一种非常糟糕的形式,因为通过截断,您失去了正确四舍五入到最接近的小数点后 2 位的能力。即 0.455 如果你只是截断你得到 0.45 这对于舍入是错误的,因为它应该导致 0.46 。永远不要截断小数,总是对数字进行四舍五入,否则结果会在四舍五入时出错。
    猜你喜欢
    • 2013-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-24
    相关资源
    最近更新 更多