Bizarre floating-point behavior with vs. without extra variables, why?

后端 未结 4 395
终归单人心
终归单人心 2021-01-18 01:27

When I run the following code in VC++ 2013 (32-bit, no optimizations):

#include 
#include 
#include 

double mulpow         


        
4条回答
  •  礼貌的吻别
    2021-01-18 02:27

    Hypothesis: It is a bug. The compiler converts double to unsigned long long correctly but converts extended-precision floating-point (possibly long double) to unsigned long long incorrectly. Details:

    double              x = std::floor(9710908999.0089989 * 1.0E9);
    

    This computes the value on the right-hand side and stores it in x. The value on the right-hand side might be computed with extended precision, but it is, as the rules of C++ require, converted to double when stored in x. The exact mathematical value would be 9710908999008998870, but rounding it to the double format produces 9710908999008999424.

    unsigned long long y1 = x;
    

    This converts the double value in x to unsigned long long, producing the expected 9710908999008999424.

    unsigned long long y2 = std::floor(9710908999.0089989 * 1.0E9);
    

    This computes the value on the right-hand side using extended precision, producing 9710908999008998870. When the extended-precision value is converted to unsigned long long, there is a bug, producing 263 (9223372036854775808). This value is likely the “out of range” error value produced by an instruction that converts the extended-precision format to a 64-bit integer. The compiler has used an incorrect instruction sequence to convert its extended-precision format to an unsigned long long.

提交回复
热议问题