将Ruby中的浮点数四舍五入到最接近的0.05。

25

我得到的数字像这样:

2.36363636363636
4.567563
1.234566465448465
10.5857447736

我该如何让 Ruby 将这些数字四舍五入到最接近的 0.05?


6
你意识到那些不是整数,对吗? - glenn jackman
9个回答

25
[2.36363636363636, 4.567563, 1.23456646544846, 10.5857447736].map do |x|
  (x*20).round / 20.0
end
#=> [2.35, 4.55, 1.25, 10.6]

真糟糕,你比我快了几秒钟!我给你点赞,尽管我心里有一个稍微不同的版本。 - Swanand
这不会像OP要求的那样四舍五入到最近的0.05,2.36……应该是2.40,而不是2.35。 - Christopher Maujean
2
@ChristopherMaujean 确实,但是(尽管标题如此),这不是OP所要求的。问题的正文说:“将这些数字四舍五入到最接近的0.05(向上或向下)”。无论如何,如果您想向上舍入,请使用ceil而不是round - sepp2k
我已经编辑了标题以反映问题,如果允许的话,我会取消我的踩。 - Christopher Maujean

21

看看这个链接,我认为它就是你需要的。 Ruby rounding

class Float
  def round_to(x)
    (self * 10**x).round.to_f / 10**x
  end

  def ceil_to(x)
    (self * 10**x).ceil.to_f / 10**x
  end

  def floor_to(x)
    (self * 10**x).floor.to_f / 10**x
  end
end

8
好的链接。但最好加上摘要,这样它就可以独立存在,特别是因为链接中的代码并没有完全按照原帖中所要求的四舍五入到最近的0.05,而是按照指定的小数位进行四舍五入。 - tvanfosson
4
更糟糕的是,由于这篇文章实际上重新实现了内置的Ruby函数 round(number-of-decimal-places),这是一个不好的想法。 - Rob
4
因为只提供一个链接而遭受负评,很不给力...而且这个链接甚至没有回答问题。 - OpenCoderX
猴子补丁可能并非必要。你需要的是通过乘以因数、应用函数,然后再除以相同的因数来实现的技术。下一个季度货币单位?使用4作为因子和“ciel.to_f”...等等... - Jerome
正如其他人指出的那样,这实际上并没有做到问题所要求的... - philomory
显示剩余2条评论

20

通常“四舍五入到最近的x”算法如下:

round(x / precision)) * precision
有时候最好乘以 1 / precision,因为这是一个整数(因此可以更快地运行):
round(x * (1 / precision)) / (1 / precision)
在你的情况下,应该这样做:
round(x * (1 / 0.05)) / (1 / 0.05)

这将被评估为:

round(x * 20) / 20;

我不了解Python,所以语法可能不正确,但我相信你可以理解。


1
为了获得小数,除以20.0 -> round(x * 20) / 20.0; - Irukandji
3
对于 Ruby 语言而言:(7.125 * 20).round / 20.0 => 7.15 - Pratik Khadloya

11

要四舍五入到最接近的两位小数:

(5.65235534).round(2)
#=> 5.65

1
5.6355.round(2) != 5.65,但 TS 希望得到 5.65。 - Dmitry Lihachev
1
这个解决方案只将数字四舍五入到小数点后两位,而不是按要求返回最接近0.05的四舍五入值。 - Scott Swezey
在某些方面,你是对的,我应该删除这个答案。但从另一个角度来看,这是一个非常受欢迎的问题,在搜索中被链接到,人们发现这个答案很有帮助,所以我会保持它可见。 - boulder_ruby

8
以下是一个通用函数,可按任意指定步长进行四舍五入:

库中的位置:

lib/rounding.rb
class Numeric
  # round a given number to the nearest step
  def round_by(increment)
    (self / increment).round * increment
  end
end

而且规格如下:
require 'rounding'
describe 'nearest increment by 0.5' do
  {0=>0.0,0.5=>0.5,0.60=>0.5,0.75=>1.0, 1.0=>1.0, 1.25=>1.5, 1.5=>1.5}.each_pair do |val, rounded_val|
    it "#{val}.round_by(0.5) ==#{rounded_val}" do val.round_by(0.5).should == rounded_val end
  end
end

并使用:
require 'rounding'
2.36363636363636.round_by(0.05)

hth.


5

Ruby 2现在有一个round函数:

# Ruby 2.3
(2.5).round
 3

# Ruby 2.4
(2.5).round
 2

在 Ruby 2.4 中也有一些选项,如::even:up:down

(4.5).round(half: :up)
 5

4

可以使用String类的%方法对数字进行四舍五入。

例如:

"%.2f" % 5.555555555

结果将是"5.56"(一个字符串)。


3
要获得一个没有小数的四舍五入结果,请使用Float的 .round
5.44.round
=> 5

5.54.round
=> 6

0

我知道这个问题很老了,但我想与世界分享我的发明,以帮助他人:这是一种用于按步骤舍入浮点数、将小数舍入到最接近的给定数字的方法;例如,它对于舍入产品价格非常有用:

def round_with_step(value, rounding)
  decimals = rounding.to_i
  rounded_value = value.round(decimals)

  step_number = (rounding - rounding.to_i) * 10
  if step_number != 0
    step = step_number * 10**(0-decimals)
    rounded_value = ((value / step).round * step)
  end

  return (decimals > 0 ? "%.2f" : "%g") % rounded_value
end

# For example, the value is 234.567
#
# | ROUNDING | RETURN | STEP
# | 1        | 234.60 | 0.1
# | -1       | 230    | 10
# | 1.5      | 234.50 | 5 * 0.1 = 0.5
# | -1.5     | 250    | 5 * 10  = 50
# | 1.3      | 234.60 | 3 * 0.1 = 0.3
# | -1.3     | 240    | 3 * 10  = 30

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接