Why does (int)55 == 54 in C++?

前端 未结 8 1248
旧巷少年郎
旧巷少年郎 2020-12-31 01:32

So I\'m learning C++. I\'ve got my \"C++ Programming Language\" and \"Effective C++\" out and I\'m running through Project Euler. Problem 1...dunzo. Problem 2...not so mu

相关标签:
8条回答
  • 2020-12-31 01:46

    Shog9 has it right, using the type double for a problem like this is not the best way to go if you are going to cast things to ints. If your compiler supports it you should use a long long or some other 64 bit integer type, that will almost certainly hold the result of the sum of all the even terms less than 4 million of the Fibonacci sequence.

    If we use the fact that the Fibonacci sequence follows the pattern odd odd even odd odd even... something as follows should do the trick.

    ...
    unsigned int fib[3];
    fib[0]=1;
    fib[1]=1;
    fib[2]=2;
    
    unsigned long long sum=0;
    
    while(fib[2]<4000000)
    {
        sum+=fib[2];
    
        fib[0]=(fib[1]+fib[2]);
        fib[1]=(fib[2]+fib[0]);
        fib[2]=(fib[0]+fib[1]);
    }
    
    std::cout<<"The sum is: "<<sum<<". \n";
    ....
    

    that should do the trick, there might be even faster ways but this one is pretty direct and easy to read.

    Looking at it I realize that you could probably get away with a standard unsigned 32 bit integer as the sum number but I will leave it as is just in case.

    Additionally your code makes a large number of function calls to the generate nth Fibonacci number function. A decent optimizing compiler will inline these calls but if it doesn't then things will slow down since function calls are more expensive than other techniques.

    0 讨论(0)
  • 2020-12-31 01:48

    Okay, short answer is that under no condition should (int)55 == 54, so you need to start asking yourself what the associated line of code is really doing.

    First question: how strongly does == bind compared to a typecast?

    0 讨论(0)
  • 2020-12-31 01:48

    I know this is not going to help with your real question, but you mentioned you're learning C++. I would recommend keeping as close to ANSI as possible, for learning purposes. I think that's /Za on MSVC (which is what you're probably using), or -ansi -pedantic on GCC.

    In particular, you should be using one of these signatures for main until you have a good (platform-specific) reason to do otherwise:

    int main(int argc, char *argv[]);
    int main(int argc, char **argv); // same as the first
    int main();
    

    ...instead of any platform-specific version, such as this (Windows-only) example:

    #include <windows.h> // defines _TCHAR and _tmain
    int _tmain(int argc, _TCHAR* argv[]); // win32 Unicode vs. Multi-Byte
    
    0 讨论(0)
  • 2020-12-31 01:50

    Due to floating point rounding, that 55 row is computing something like 54.99999. Casting double to int truncates the .99999 right off.

    On my machine, printing a column displaying (currentFib-(int)currentFib) shows errors on the order of 1.42109e-14. So it's more like 0.999999999999986.

    0 讨论(0)
  • 2020-12-31 01:50

    All the above suggestions not to use floating point values for integer mathematics are worth noting!

    If you want integer "rounding" for positive floating point values so that values with a fractional component below 0.5 round to the next lowest integer, and values with a fractional component of 0.5 or greater round to the next higher integer, e.g.

    0.0 = 0
    0.1 = 0
    0.5 = 1
    0.9 = 1
    1.0 = 1
    1.1 = 1
    ...etc...    
    

    Add 0.5 to the value you are casting.

    double f0 = 0.0;
    double f1 = 0.1;
    double f2 = 0.5;
    double f3 = 0.9;
    
    int i0 = ( int )( f0 + 0.5 );  // i0 = 0
    int i1 = ( int )( f1 + 0.5 );  // i1 = 0
    int i2 = ( int )( f2 + 0.5 );  // i2 = 1
    int i3 = ( int )( f3 + 0.5 );  // i3 = 1
    
    0 讨论(0)
  • 2020-12-31 02:09

    Casting to int truncates the number - same as if you'd called floor(currentFib). So even if currentFib is 54.999999... (a number so close to 55 that it will be rounded up when printed), (int)currentFib will produce 54.

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