I noticed that with Visual Studio there are precision errors when adding double to long long. For example:
long long a = 44981600439878676;
double b = 234567890;
a += b;
The result of a is 44981600674446560 but should be 44981600674446566. It happens for both x32 and x64.
However the following returns the correct value:
long long a = 44981600439878676;
double b = 234567890;
a += (long long)b;
I noticed in the disassembly that in the first case without the explicit cast, there is
0116A892 call __ltod3 (011619DDh)
0116A897 addsd xmm0,mmword ptr [b]
0116A89C call __dtol3 (01161A05h)
While in the second case __ltod3 is not called. I am explaining this with VC++ compiler by default converting first long long to double and then again double to long long because double is more simple type than long long. In this way we lose precision because of the __ltod3 and int64 containing too big value. But from another hand, a is l-value and in this case, because compiler knows that the output would be long long, it looks unnecessary to convert the left side first to double and then again to long long during the addition. Also it is very easy someone to make errors and to omit the explicit cast because precision errors would become visible only for certain numbers.
Is this double conversion part of the C++ standard or is implementation of VS?