Unexpected result after converting uint64_t to double

In the following code:

#include <iostream>

...

uint64_t t1 = 1510763846;
uint64_t t2 = 1510763847;
double d1 = (double)t1;
double d2 = (double)t2;
// d1 == t2 => evaluates to true somehow?
// t1 == d2 => evaluates to true somehow?
// d1 == d2 => evaluates to true somehow?
// t1 == t2 => evaluates to false, of course.
std::cout << std::fixed << 
        "uint64_t: " << t1 << ", " << t2 << ", " <<
        "double: " << d1 << ", " << d2 << ", " << (d2+1) << std::endl;

I get this output:

uint64_t: 1510763846, 1510763847, double: 1510763904.000000, 1510763904.000000, 1510763905.000000

And I don’t understand why. This answer: the largest integer that can be stored in double , says that an integer up to 2 ^ 53 (9007199254740992) can be stored in doublewithout loss of precision.

I really get errors when I start doing duplicate calculations, so this is not just a printing problem. (e.g., 1510763846 and 1510763847 both give 1510763904).

It is also very strange that a double can simply be added and then exited correctly (d2 + 1 == 1510763905.000000)

: , Lua, . , Lua lib double lua_Number, float.

std::cout << sizeof(t1) << ", " << sizeof(d2) << std::endl;

8, 8

VS 2012 MachineX86, toolkit v110_xp. " (/fp: exact)"

, Visual Studio 2008?, , _set_controlfp, _control87, _controlfp __control87_2, "single". uint64_t double , float.

"MCW_PC", Precision Control, , :

  • Android NDK
  • ::
  • ::
  • DirectX ( 2010 .)
  • FMod ( EX)

:

, uint64_t double , :

  • _fpreset() , ( )
  • , _fpreset() ?

:

double toDouble(uint64_t i)
{
    double d;
    do {
        _fpreset();
        d = i;
        _fpreset();
    } while (d != i);
    return d;
}

double toDouble(int64_t i)
{
    double d;
    do {
        _fpreset();
        d = i;
        _fpreset();
    } while (d != i);
    return d;
}

, . , , , - , . . ?

+4
1

ieee754 , double float, , , , , sizeof double >= sizeof float.

1510763846 - 1.510763904E9.

+1

Source: https://habr.com/ru/post/1689328/


All Articles