ruby-on-rails - 如何将小数舍入到 Ruby 中的第一个有效数字

标签 ruby-on-rails ruby algorithm decimal

我正在尝试解决与个人项目相关的任务的边缘案例。

确定一个服务的单价,由total_amountcost组成。

示例包括:

# 1
unit_price = 300 / 1000 # = 0.3

# 2
unit_price = 600 / 800 # = 0.75

# 3
unit_price = 500 / 1600 # = 0.3125

对于 1 和 2,unit_prices 可以保持不变。对于 3,四舍五入到小数点后两位就足够了,例如(500/1600).round(2)

当 float 变长时出现问题:

# 4
unit_price = 400 / 56000 # = 0.007142857142857143

很明显, float 相当长。在这种情况下,目标是四舍五入到第一个有效数字。

我考虑过使用正则表达式来匹配第一个非零小数,或者找到第二部分的长度并应用一些逻辑:

  • unit_price.match ~=/[^.0]/
  • unit_price.to_s.split('.').last.size

非常欢迎任何帮助

最佳答案

应该使用 BigDecimal对于这种计算。

require 'bigdecimal'

bd = BigDecimal((400.0 / 56000).to_s)
#⇒ 0.7142857142857143e-2
bd.exponent
#⇒ -2

示例:

[10_000.0 / 1_000, 300.0 / 1_000, 600.0 / 800,
                   500.0 / 1_600, 400.0 / 56_000].
  map { |bd| BigDecimal(bd.to_s) }.
  map do |bd|
    additional = bd.exponent >= 0 ? 0 : bd.exponent + 1 
    bd.round(2 - additional) # THIS
  end.
  map(&:to_f)
#⇒ [10.0, 0.3, 0.75, 0.31, 0.007]

关于ruby-on-rails - 如何将小数舍入到 Ruby 中的第一个有效数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57115640/

相关文章:

ruby-on-rails - ruby json新换行符渲染格式不正确

algorithm - 当两个数组有序时,什么地方排序?

algorithm - 这个算法的大(O)

ruby-on-rails - 带有 Rails 4 的 ActiveRecord 信誉系统 gem

ruby-on-rails - "<<"在 ruby​​ 中到底做了什么?

ruby-on-rails - RailsWizard 中排序算法的问题

javascript - 最小公倍数 : What is wrong with my code?

mysql - Rails - 用同一张表的另一列检查列

ruby-on-rails - 时间为 Rails 3 选择 12 小时格式的表单助手?

Ruby 检查可读性?