Thread overview
[Issue 1681] New: cast(real) ulong.max == 0
Nov 21, 2007
d-bugmail
Nov 21, 2007
d-bugmail
Nov 21, 2007
d-bugmail
Jan 20, 2008
d-bugmail
Jan 20, 2008
d-bugmail
Feb 19, 2009
d-bugmail
Mar 11, 2009
d-bugmail
Apr 08, 2009
d-bugmail
November 21, 2007
http://d.puremagic.com/issues/show_bug.cgi?id=1681

           Summary: cast(real) ulong.max == 0
           Product: D
           Version: 2.007
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: bugzilla@digitalmars.com
        ReportedBy: andrei@metalanguage.com


The title says it all. Here's a test:

import std.stdio;
import std.conv;

void main()
{
    real r = ulong.max;
    ulong d = cast(ulong) r;
    writeln(d);
    assert(d == ulong.max); // should not fail
}


-- 

November 21, 2007
http://d.puremagic.com/issues/show_bug.cgi?id=1681





------- Comment #2 from andrei@metalanguage.com  2007-11-21 14:23 -------
(In reply to comment #1)
> Real is a floating point type, typically 80 bits. Ulong is a 64-bit integer type. Real is not capable of holding a value as large as ulong.max. That is why the assert fails.

Float must store integers with proper successors up to 2 ** 24 - 1. Double must store integers with proper successors up to 2 ** 53 - 1. Real (i.e. "double-extended") must store integers with proper successors up to at least 2 ** 64 - 1. The program prints 0.


-- 

November 21, 2007
http://d.puremagic.com/issues/show_bug.cgi?id=1681





------- Comment #3 from wbaxter@gmail.com  2007-11-21 14:44 -------
(In reply to comment #2)
> (In reply to comment #1)
> > Real is a floating point type, typically 80 bits. Ulong is a 64-bit integer type. Real is not capable of holding a value as large as ulong.max. That is why the assert fails.
> 
> Float must store integers with proper successors up to 2 ** 24 - 1. Double must store integers with proper successors up to 2 ** 53 - 1. Real (i.e. "double-extended") must store integers with proper successors up to at least 2 ** 64 - 1. The program prints 0.
> 

This is also interesting:

    writefln("ulong.max      %-30d", ulong.max);
    writefln("real ulong.max %-30f", cast(real)ulong.max);

-->

ulong.max      18446744073709551615 real ulong.max 18446744073709551613.000000


-- 

January 20, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1681


baryluk@mpi.int.pl changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |baryluk@mpi.int.pl




------- Comment #4 from baryluk@mpi.int.pl  2008-01-20 09:13 -------
writefln("ulong.max      %-30d", ulong.max);
writefln("real ulong.max %-30f", cast(real)ulong.max);

gdc (GCC) 4.1.3 20080114 (prerelease gdc 0.25 20071124, using dmd 1.022)
(Debian 0.25-4.1.2-19)

ulong.max      18446744073709551615 real ulong.max 18446744073709551615.000000

dmd 1.025:

ulong.max      18446744073709551615 real ulong.max 18446744073709551615.000000

This can depend on processor (some processors aren't strictly following IEEE 754, especially in extented precission). Also real isn't nacassary 80bit, real can be double on some architectures and processors. As far as I known Intel processors do real extended precission operations (in fact they use internally 128 bit precission).


Tested machines:
Debian GNU/Linux etch, Pentium III (Coppermine) 733MHz
Debian GNU/Linux unstable, Intel(R) Pentium(R) 4 CPU 2.80GHz
Debian GNU/Linux etch, AMD Duron 1200MHz (Unknown model)


Unfortunetly example from first post gives 0 in dmd (gdc works), so it is a
bug.


The largest integer real which gives nonzero result after cast is
18446744073709550591.000000
18446744073709549568
but as you can see it gives wrong result. Then it is skiping every 2048 (11
bits), with some values correct:
18446744073709549568.000000
18446744073709549568
but most not.

Largest continues interval with correct answers:
0.0 ... 8744073709552616.000000  (about 2**53, so doubles are involved not
real!)

(similar in decimal expansion 18446744073709551615.000000, but probably
coincidence)


-- 

January 20, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1681





------- Comment #5 from baryluk@mpi.int.pl  2008-01-20 09:15 -------
> 
> The largest integer real which gives nonzero result after cast is
> 18446744073709550591.000000
> 18446744073709549568
> but as you can see it gives wrong result. Then it is skiping every 2048 (11
> bits), with some values correct:

53+11 = 64


-- 

February 19, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=1681


clugdbug@yahoo.com.au changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Version|2.007                       |1.023




------- Comment #6 from clugdbug@yahoo.com.au  2009-02-19 07:12 -------
Also applies in D1.0


-- 

March 11, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=1681





------- Comment #7 from bugzilla@digitalmars.com  2009-03-11 14:52 -------
Fixed dmd 1.041 and 2.026


-- 

April 08, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=1681


clugdbug@yahoo.com.au changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |FIXED




--