转换为int vs floor


120

这些之间有什么区别:

float foo1 = (int)(bar / 3.0);
float foo2 = floor(bar / 3.0);

据我了解,两种情况都有相同的结果。编译后的代码有什么区别吗?


1
使用会更好floor,但是请注意这double不是为了float。C99还具有floorffloat
詹斯·古斯特

2
因此,只要bar为正,它们就会得到相同的结果
Zac

1
(注意:请#include<cmath>使用C ++ 并使用std::floor
user202729 '18

什么类型的bar
chux-恢复莫妮卡

@chux无所谓,3.0分将使它成为双反正
kaalus

Answers:


193

强制转换为int将截断为零。 floor()将截断为负无穷大。如果bar为负,这将为您提供不同的值。


15
我想你在这里钉了钉子。如果floor()是目的,则另一个不同是如果的值bar太大而不能放入int
Fred Larson

您有该声明的任何来源吗?
HelloGoodbye

1
即使结果是肯定的,也不能保证。看到这个这个
user202729 '18

27

如前所述,对于正数,它们是相同的,但是对于负数,它们是不同的。规则是int取整为0,而floor取整为负无穷。

floor(4.5) = (int)4.5 = 4
floor(-4.5) = -5 
(int)(-4.5) = -4

话虽如此,执行时间也有所不同。在我的系统上,我已确定投放时间至少比地面快3倍。

我的代码需要在有限范围内(包括负数)进行取整运算。而且它必须非常高效,因此我们使用以下功能:

int int_floor(double x) 
{ 
    return (int)(x+100000) - 100000; 
}

当然,如果x的值非常大(您将遇到一些溢出问题)以及低于-100000的负值,这将失败,但是我认为它至少比下限快3倍,这非常关键为我们的应用程序。带着一粒盐,在您的系统上测试它,等等。但是值得考虑恕我直言。


“我已经指出它至少比底层速度快3倍”-> OP正在使用float,不是double-也许double是您的应用程序。如果在C中,请确保floorf()floats 一起使用。
chux-恢复莫妮卡

@chux我认为没有任何区别的唯一原因是强制转换允许编译时优化。因此,转换实际上可能在执行期间已被完全删除。
ClydeTheGhost

9

SO 101,在人们回答您的问题后不要更改您的问题,而要写一个新的问题。

您为什么认为他们会有相同的结果?

float foo = (int)(bar / 3.0) //will create an integer then assign it to a float

float foo = fabs(bar / 3.0 ) //will do the absolute value of a float division

bar = 1.0

foo1 = 0;
foo2 = 0.33333...

1
你是什​​么意思fabs?问题是关于floor。...的地板0.333330
亚伦·弗兰克

2
@AaronFranke原始问题已被修改。似乎在8年内可能会发生很多事情;-)注意其他答案具有相同的前提
AndersK

4

编辑:因为fabs()和之间的混淆,该问题可能已被修改floor()

给定原始问题示例行:

1.  float foo = (int)(bar / 3.0);

2.  float foo = fabs(bar / 3.0);

所不同的是,如果bar为负,则第一个结果为负,而第二个结果为正。第一个将被截断为整数,第二个将返回完整的十进制值(包括小数部分)。


3

是。fabs返回其参数的绝对值,并将其强制转换为int会导致除法截断(向下至最接近的int),因此结果几乎总是不同的。


2

有两个主要区别:

  1. 正如其他人指出的那样,强制转换为整数将截断为零,而floor()始终将截断为负无穷大。对于负操作数,这是不同的行为。

  2. 似乎还没有人指出另一种差异-如果您的论点大于或等于MAX_INT+1(或小于-MAX_INT-1),则强制转换为int会导致最高位被丢弃(可能是C)或未定义的行为( C ++,也可能是C)。EG如果您int是32位,则只有符号位加上31位数据。因此,将其与double较大的尺寸一起使用会产生意想不到的结果。


2.a. 转换为int溢出的确切条件是该参数大于或等于INT_MAX+1。对称地,下溢的条件是参数小于或等于INT_MIN-1。
Pascal Cuoq 2014年

1
2.b. 从浮点到整数的转换中的溢出是C ++中未定义的行为。它不会“导致最高位被丢弃”。参见(尽管它是为C写的):blog.frama-c.com/index.php?post/2013
Pascal Cuoq

0

(int) x 是一个要求保留整数部分的请求 x(此处没有舍入)

fabs(x)= | x | 所以它是>= 0;

例如:(int) -3.5退货-3fabs(-3.5)回报3.5;

通常, fabs (x) >= x对于所有x;

x >= (int) x 如果 x >= 0

x < (int) x 如果 x < 0


x = -3 fabs(-3)= 3(整数)-3 = -3; 我认为最后的不平等现象仍然存在。您能详细说明为什么会出错吗?
Paul Hoang,2010年

抱歉,我的意思是-3.5,您给出的示例。-3> -3.5
Dennis Zickefoose 2010年

3
最后一条语句仍应为“如果x <0时x <= int(x)”,而不是“如果x <0则x <(int)x”:负整数保持不变。
Tomasz Gandor 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.