These days, in my spare time, I've been thinking all your answers and getting mulled over instructions for the processor, bitwise operations, numerical representation ... I came to the conclusion that the huge amount of knowledge that I should learn about, is too large for my mind (takes a lot of memory and slows down my daily routines), so at the moment I will settle for converting with C explicit cast from double to long long and setting limits from 0 to 0x7fffffffffffffff; this for my purpose it's sufficient.
A first time I got problems in testing the bitwise Timo's routine, but then I find that the constant "1" is represented by the compiler as a 32 bit integher, and it cannot be shifted by 63. So I replaced it with a const variable of type unsigned long long and now works perfectly, with 15 digit precision as minimum! (the max accuracy achievable by a double floating point value). I think for the same reason that the entering value cannot exceed approximately 18446744073709550000.0 that is ULLONG_MAX rounded down by the floating point double precision value maximum accurancy.
I have not run an accurate test, and so I could be wrong, but it seemed to be not faster than C esplicit casting, and for a large number of iterations it could be numerically instable. however, I packed it this way:
typedef unsigned long long ULL;
typedef unsigned long long *PULL;
__forceinline
ULL __d_to_ull(double x)
{
static const ULL k = 1;
const ULL y = *(PULL)&x;
const ULL e = 0x3FF + 63 - (y >> 52);
return (k << 63 | y << 11) >> e & -(e < 64);
}
Concerning the root of the problem, it might be the way in which the compiler translates instructions, for example, from
"Intel® 64 and IA-32 Architectures Software Developer’s Manual - September 2013":
CVTTSD2SI - Convert with Truncation Scalar Double-Precision FP Value to Signed Integer
...
When a conversion is inexact, a truncated (round toward zero) result is returned. If a converted result is larger than the maximum signed doubleword integer, the floating-point invalid exception is raised. If this exception is masked, the indefinite integer value (80000000H) is returned.
It does not say anything then, about this on 64-bit operation, but it's likely that converting one double value from xmm/m64 to one signed quadword integer in r64 (CVTTSD2SI r64, xmm/m64) it will returns 8000000000000000H.
Thanks to all of you for this appreciated debate