Cast to int vs floor

前端 未结 7 1597
夕颜
夕颜 2020-11-27 14:25

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 sa

相关标签:
7条回答
  • 2020-11-27 14:28

    EDIT: Because the question may have been modified due to confusion between fabs() and 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.

    0 讨论(0)
  • 2020-11-27 14:34

    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.

    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.

    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.

    0 讨论(0)
  • 2020-11-27 14:38

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

    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...
    
    0 讨论(0)
  • 2020-11-27 14:39

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

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

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

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

    x >= (int) x if x >= 0

    x < (int) x if x < 0

    0 讨论(0)
  • 2020-11-27 14:42

    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 int will result in the top-most bits being dropped (C, probably) or undefined behaviour (C++ and possibly C). EG if your int is 32 bits, you will only have a sign bit plus 31 bits of data. So using this with a double that is large in size is going to produce unintended results.

    0 讨论(0)
  • 2020-11-27 14:43

    Yes. fabs returns 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.

    0 讨论(0)
提交回复
热议问题