英文:
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_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
支持不同的四舍五入模式。
: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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论