C++ 投射到 int vs floor

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3300290/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 12:34:24  来源:igfitidea点击:

Cast to int vs floor

c++cfloating-point

提问by OgreSwamp

Is there any difference between these:

这些有什么区别吗:

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

As I understand both cases have the same result. Is there any difference in the compiled code?

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

回答by James Curran

Casting to an int will truncate toward zero. floor()will truncate toward negative infinite. This will give you different values if barwere negative.

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

回答by brice rebsamen

As was said before, for positive numbers they are the same, but they differ for negative numbers. The rule is that int rounds towards 0, while floor rounds towards negative infinity.

如前所述,对于正数它们是相同的,但是对于负数它们不同。规则是 int 向 0 舍入,而 floor 向负无穷大舍入。

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

This being said, there is also a difference in execution time. On my system, I've timed that casting is at least 3 times faster than floor.

话虽如此,执行时间也有所不同。在我的系统上,我已经确定了施法速度至少比地板快 3 倍。

I have code that needs the floor operation of a limited range of values, including negative numbers. And it needs to be very efficient, so we use the following function for it:

我的代码需要对有限范围的值(包括负数)进行地板运算。并且它需要非常高效,因此我们使用以下函数:

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

Of course this will fail for very large values of x (you will run into some overflow issues) and for negative values below -100000, etc. But I've clocked it to be at least 3 times faster than floor, which was really critical for our application. Take it with a grain of salt, test it on your system, etc. but it's worth considering IMHO.

当然,对于非常大的 x 值(您会遇到一些溢出问题)和低于 -100000 的负值等,这将失败。但我已经将它计时至少比 floor 快 3 倍,这非常关键对于我们的应用程序。带着一丝盐分,在你的系统上测试它,等等,但恕我直言,这是值得考虑的。

回答by AndersK

SO 101, do not change your question after people have replied to your question, instead write a new question.

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

Why do you think they will have the same result?

为什么你认为他们会有同样的结果?

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...

回答by Amardeep AC9MF

EDIT: Because the question may have been modified due to confusion between fabs()and floor().

编辑:因为问题可能由于 和 之间的混淆fabs()而被修改floor()

Given the original question example lines:

鉴于原始问题示例行:

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

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

The difference is that if bar is negative the result will be negative with the first but positive with the second. The first will be truncated to an integer and the second will return the full decimal value including fractional part.

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

回答by warrenm

Yes. fabsreturns the absolute value of its argument, and the cast to int causes truncation of the division (down to the nearest int), so the results will almost always be different.

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

回答by abligh

There are two main differences:

有两个主要区别:

  1. As others have pointed out, casting to an integer will truncate towards zero, whereas floor()will always truncate towards negative infinity; this is different behaviour for a negative operand.

  2. No one (yet) seems to have pointed out another difference - if your argument is greater than or equal to MAX_INT+1(or less than -MAX_INT-1) then casting to an intwill result in the top-most bits being dropped (C, probably) or undefined behaviour (C++ and possibly C). EG if your intis 32 bits, you will only have a sign bit plus 31 bits of data. So using this with a doublethat is large in size is going to produce unintended results.

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

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

回答by Paul Hoang

(int) xis a request to keep the integer part of x(there is no rounding here)

(int) x是保留整数部分的请求x(这里没有四舍五入)

fabs(x)= |x| so that it's >= 0;

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

Ex: (int) -3.5returns -3; fabs(-3.5)returns 3.5;

例如:(int) -3.5返回-3fabs(-3.5)返回3.5

In general, fabs (x) >= xfor all x;

一般来说, fabs (x) >= x对于所有的 x;

x >= (int) xif x >= 0

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

x < (int) xif x < 0

x < (int) x如果 x < 0