截断浮点数而不向上舍入

问题描述 投票:0回答:9

我有一个浮点数,我想截断到 3 位,但我不想四舍五入。

例如,将

1.0155555555555555
转换为
1.015
(而不是
1.016
)。

我该如何在 Ruby 中做到这一点?

ruby math floating-point decimal precision
9个回答
25
投票

您还可以转换为 BigDecimal,并对其调用 truncate。

1.237.to_d.truncate(2).to_f # will return 1.23

22
投票

假设您有

float
,请尝试以下操作:

(x * 1000).floor / 1000.0

结果:

1.015

查看它在线运行:ideone


18
投票

ruby 2.4

Float#truncate
方法将一些十进制数字作为可选参数:

1.0155555555555555.truncate(3)
# => 1.015

7
投票

乘以千,取整,除以千,确保进行浮点除法。

(x * 1000).floor / 1000.0

或者,在 Ruby 1.9.2 中,使用早期版本中不可用的 round 版本,

(x - 0.0005).round(3)

3
投票

sid 的答案很好,但它错过了第一个要求,因此未通过 Anwar 的测试。那里的要求是我们必须从原始开始,这样 ruby 就不会轻易转换数字。并且像原始获取一样开始原始是使用纯字符串,所以

> "59.99999999999999999999".to_d.截断(2)
=> #BigDecimal:55a38a23cd68,'0.5999E2',18(45)>
> "59.99999999999999999999".to_d.truncate(2).to_s
=>“59.99”
> "59.99999999999999999999".to_d.truncate(2).to_f
=> 59.99

现在就分享这个,因为我今天自己也遇到了这个问题:)


0
投票

该解决方案基于@SidKrishnan 的绝妙 BigDecimal 技巧,但也可以处理更大的浮点数,而不会在精度问题上出现问题。

# Truncate a floating-point value without rounding up.
#
#   trunc_float(1.999, 2)   # => 1.99
#   trunc_float(1.999, 0)   # => 1.0
#
# @param value [Float]
# @param precision [Integer]
# @return [Float]
def trunc_float(value, precision)
  BigDecimal(value.to_s).truncate(precision).to_f
end

#--------------------------------------- Test

describe ".trunc_float" do
  def call(*args)
    trunc_float(*args)
  end

  it "generally works" do
    [
      [[1, 0], 1.0],
      [[1.999, 4], 1.999],
      [[1.999, 3], 1.999],
      [[1.999, 2], 1.99],
      [[1.999, 1], 1.9],
      [[1.999, 0], 1.0],
      [[111111111.9999999, 3], 111111111.999],
      [[1508675846.650976, 6], 1508675846.650976],
    ].each do |input, expected|
      output = call(*input)
      expect([input, output]).to eq [input, expected]
    end
  end
end

0
投票

我看到更“计算”的方式并不在答案中。您可以考虑使用下面的方法。

这也适用于其他编程语言,例如 C/Java/Python 等(但是转换语法会有所不同)。

q = 1.0155555555555555
(q * 1000).to_i / 1000.0
=> 1.015

0
投票

您的选择很少 - 上面的答案中提到了其中一些,但不是全部。

您可以使用

.floor(n)

# Returns the largest number less than or equal to
# float with a precision of n digits decimal digits (default: 0).
# -> basically its rounding down the number

> 1.0155555555555555.floor(3)
1.015

您可以使用

.truncate(n)

# Returns float truncated to a precision 
# of n digits decimal digits (default: 0).

> 1.0155555555555555.truncate(3)
=> 1.015

您可以使用

.round(n, :truncate)
(仅适用于
BigDecimal
,不适用于
float

> 1.0155555555555555.to_d.round(3, :truncate).to_f
=> 1.015

-1
投票

您可以使用正则表达式来完成此操作,因为 ruby/rails 有精度限制。

-- 首先将数字转换为字符串,然后执行以下操作 -

输入=“114.99999999999999999999”

输入[/\d+.\d/]

114.99

© www.soinside.com 2019 - 2024. All rights reserved.