英文:
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 floatFloat#ceil: Round up to the nearest integerFloat#floor: Round down to the nearest integerFloat#round: Round to the nearest integerFloat#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_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);
}
还有 truncate,它的行为类似于 to_i,但接受可选的小数位数参数(类似于 floor、ceil 和 round)。
英文:
floor(without arguments) returns the next integer less than or equal to the receiverceil(without arguments) returns the next integer greater than or equal to the receiverto_idiscards 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 支持不同的四舍五入模式。
:up或nil:向远离零的方向四舍五入:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论