NO

Author Topic: usigned __int64 overflow question  (Read 13685 times)

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2113
Re: usigned __int64 overflow question
« Reply #15 on: December 22, 2013, 12:49:43 PM »
Timo already cleverly showed up the point. 8)

Anyway what's nice in internet is that anybody can say what they sincerly think is rigth  :D
But unfortunately expertise and knowledge don't shows up easily unless who reads has an enough valid technological background  :(
The basic problem is that high level languages performs type checking, something that is completely absent on low level coding like assembly.
Passing a QWORD to an integer store function simply implies that the FPU loads the equivalent int and convert it to the float that represent what it expects: a signed integer  ::)
Converting back you will get the same value as signed integer, but this doesn't mean that works like a charm  :-\
If you simply add 1.0 in the FPU and then convert back to int will you get what you expected ?  8)
Type checking implies automatic convertions that are carried out autonomally by compiler, that, *again*, doesn't mean that the compiler is bad, but that probably who use it ignores what is and how works an optimized compiler....  ::)
I will add nothing more to this thread because I have nothing more to say.
Happy Sunday.  :D
« Last Edit: December 22, 2013, 01:12:22 PM by frankie »
"It is better to be hated for what you are than to be loved for what you are not." - Andre Gide

Offline jj2007

  • Member
  • *
  • Posts: 536
Re: usigned __int64 overflow question
« Reply #16 on: December 22, 2013, 01:49:22 PM »
Example for POAsm

Thanks. Your code is highly compatible with Masm and even MasmBasic ;-)

And it just helped me to discover why the old CRT library fails with certain formats: They failed to implement llX and llu properly >:(

@Frankie: "unfortunately expertise and knowledge don't shows up easily unless who reads has an enough valid technological background"

Yes, I have understood that you are German. Frohe Weihnachten.

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2113
Re: usigned __int64 overflow question
« Reply #17 on: December 22, 2013, 02:54:37 PM »
JJ I wouldn't be offensive to nobody.
Please excuse me if my words were not polite and could be misinterpreted   :'(
Yes you're rigth on work some call me 'the deutsch" for my mind orientation  ;D
But I'm proudly italian, "Buon Natale"  :)
"It is better to be hated for what you are than to be loved for what you are not." - Andre Gide

Offline jj2007

  • Member
  • *
  • Posts: 536
Re: usigned __int64 overflow question
« Reply #18 on: December 22, 2013, 04:17:14 PM »
Non c'è problema, Buon Natale anche a te :)

Anyway what's nice in internet is that anybody can say what they sincerly think is rigth  :D
But unfortunately expertise and knowledge don't shows up easily unless who reads has an enough valid technological background  :(
The basic problem is that high level languages performs type checking, something that is completely absent on low level coding like assembly.

We are working on it...

include \masm32\MasmBasic\MasmBasic.inc        ; download
MyLongLong    LONGLONG    12345678901234567890
MyDword       DWORD       1234567890
MyWord        WORD        12345
MyByte        BYTE        123
MySingle      REAL4       12345678901234567890.0
MyDouble      REAL8       12345678901234567890.0
MyR10         REAL10      1234567890123456789012.0

  Init
  mov eax, MyDword
  mov bx, MyWord
  mov cl, MyByte
  fldpi                 ; PI, 3.14159
  fldl2e                ; Log2(e), 1.4427
  fldlg2                ; Log10(2), 0.3013
  movlps xmm0, MyLongLong
  deb 4, "No type checking needed??", eax, bx, cl, ST(0), ST(1), ST(2), u:xmm0, u:MyLongLong, MyDword, MyWord, MyByte
  Inkey
  Exit
end start

Output:
No type checking needed??
eax             1234567890
bx              12345
cl              123
ST(0)           0.301029995663981195
ST(1)           1.44269504088896341
ST(2)           3.14159265358979324
u:xmm0          12345678901234567890
u:MyLongLong    12345678901234567890
MyDword         1234567890
MyWord          12345
MyByte          123
MySingle        1.234568e+19
MyDouble        1.234567890123457e+19
MyR10           1.23456789012345679e+21
« Last Edit: December 22, 2013, 04:19:06 PM by jj2007 »

PaoloC13

  • Guest
Re: usigned __int64 overflow question
« Reply #19 on: December 27, 2013, 05:14:56 PM »
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:

Code: [Select]
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":

Quote
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