Float#floor 和 Float#to_i 在 Ruby 中有什么区别?

huangapple go评论81阅读模式
英文:

What's the difference between Float#floor and Float#to_i in Ruby?

问题

以下是翻译好的部分:

我正在学习Ruby,目前正在学习数字部分。据我理解,有五种方法(也许还有更多)可以将整数和浮点数相互强制转换:

  • Integer#to_f:强制转换为新的浮点数
  • Float#ceil:四舍五入到最接近的整数
  • Float#floor:向下舍入到最接近的整数
  • Float#round:四舍五入到最接近的整数
  • Float#to_i:截断到最接近的整数

“向下舍入”和“截断到最接近的整数”之间有什么区别?

当我进行测试时…

puts 34.4.to_i()
puts 34.4.floor()

…结果是相同的值:

34
34
英文:

I'm learning Ruby, and I'm currently in numbers. So as I understand it, there are five ways (perhaps more) to coerce integers and floats to each other:

  • Integer#to_f: Coerce to a new float
  • Float#ceil: Round up to the nearest integer
  • Float#floor: Round down to the nearest integer
  • Float#round: Round to the nearest integer
  • Float#to_i: Truncate to the nearest integer

What's the difference between "rounding down" and "truncating" to the nearest integer?

When I tested it...

puts 34.4.to_i()
puts 34.4.floor()

... it resulted in the same values:

34
34

答案1

得分: 6

  • floor(无参数)返回小于或等于接收器的下一个整数。
  • ceil(无参数)返回大于或等于接收器的下一个整数。
  • to_i 丢弃接收器的小数部分并返回整数部分。
f f.to_i f.floor f.ceil f.round
11.8 11 11 12 12
11.5 11 11 12 12
11.2 11 11 12 11
11.0 11 11 11 11
-11.2 -11 -12 -11 -11
-11.5 -11 -12 -11 -12
-11.8 -11 -12 -11 -12

to_i 对正数的行为类似于 floor,对负数的行为类似于 ceil

实际上,这就是 Float#to_inumeric.c 中的实现方式:

static VALUE
flo_to_i(VALUE num)
{
    double f = RFLOAT_VALUE(num);

    if (f > 0.0) f = floor(f);
    if (f < 0.0) f = ceil(f);

    return dbl2ival(f);
}

还有 truncate,它的行为类似于 to_i,但接受可选的小数位数参数(类似于 floorceilround)。

英文:
  • floor (without arguments) returns the next integer less than or equal to the receiver
  • ceil (without arguments) returns the next integer greater than or equal to the receiver
  • to_i discards the fractional part of the receiver and returns the integer part
f f.to_i f.floor f.ceil f.round
11.8 11 11 12 12
11.5 11 11 12 12
11.2 11 11 12 11
11.0 11 11 11 11
-11.2 -11 -12 -11 -11
-11.5 -11 -12 -11 -12
-11.8 -11 -12 -11 -12

to_i behaves like floor for positive numbers and like ceil for negative numbers.

In fact, that's actually how Float#to_i is implemented in numeric.c:

static VALUE
flo_to_i(VALUE num)
{
    double f = RFLOAT_VALUE(num);

    if (f > 0.0) f = floor(f);
    if (f < 0.0) f = ceil(f);

    return dbl2ival(f);
}

There's also truncate which behaves like to_i but takes an optional number of digits (like floor, ceil, and round).

答案2

得分: 5

to_i 基本上只会从浮点数中移除小数部分,而 floor 会将其舍入到下一个较低的整数。这个差异在处理负浮点数时更容易看出来:

-34.4.floor
# => -35

-34.4.to_i
# => -34

值得注意的是 Float#round 支持不同的四舍五入模式。

  • :upnil:向远离零的方向四舍五入:
2.5.round(half: :up)      # => 3
3.5.round(half: :up)      # => 4
(-2.5).round(half: :up)   # => -3
  • :down:向零的方向四舍五入:
2.5.round(half: :down)    # => 2
3.5.round(half: :down)    # => 3
(-2.5).round(half: :down) # => -2
  • :even:向最后一个非零数字为偶数的候选值方向四舍五入:
2.5.round(half: :even)    # => 2
3.5.round(half: :even)    # => 4
(-2.5).round(half: :even) # => -2
英文:

The difference is that to_i basically only removes decimals from the float. Whereas float rounds down to the next lower integer. The difference is easier to see when dealing with negative floats:

-34.4.floor
#=> -35

-34.4.to_i
#=> -34

And it might be worth noting that Float#round supports different rounding modes.

`:up` or `nil`: round away from zero:

2.5.round(half: :up)      # => 3
3.5.round(half: :up)      # => 4
(-2.5).round(half: :up)   # => -3

`:down`: round toward zero:

2.5.round(half: :down)    # => 2
3.5.round(half: :down)    # => 3
(-2.5).round(half: :down) # => -2

`:even`: round toward the candidate whose last nonzero digit is even:

2.5.round(half: :even)    # => 2
3.5.round(half: :even)    # => 4
(-2.5).round(half: :even) # => -2

huangapple
  • 本文由 发表于 2023年6月5日 13:15:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/76403628.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定