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

Saf*_*een 2 ruby floating-point numbers

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

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

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

当我测试它时...

puts 34.4.to_i()
puts 34.4.floor()
Run Code Online (Sandbox Code Playgroud)

...它产生了相同的值:

34
34
Run Code Online (Sandbox Code Playgroud)

Ste*_*fan 6

  • floor(不带参数)返回小于或等于接收者的下一个整数
  • ceil(不带参数)返回大于或等于接收者的下一个整数
  • to_i丢弃接收者的小数部分并返回整数部分
F f.to_i f.地板 细胞因子 f.圆形
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_i实现的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);
}
Run Code Online (Sandbox Code Playgroud)

还有truncate它的行为类似to_i,但采用可选的数字位数(如floorceilround)。


spi*_*ann 5

区别在于to_i基本上只从浮点数中删除小数。而向下float舍入到下一个较小的整数。在处理负浮点数时,差异更容易看出:

-34.4.floor
#=> -35

-34.4.to_i
#=> -34
Run Code Online (Sandbox Code Playgroud)

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

`: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
Run Code Online (Sandbox Code Playgroud)