Bug 3970 – Problem with cast -1.0L ==> uint/ulong

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
x86
OS
Windows
Creation time
2010-03-15T11:03:00Z
Last change time
2014-02-15T02:44:25Z
Keywords
wrong-code
Assigned to
nobody
Creator
bearophile_hugs

Comments

Comment #0 by bearophile_hugs — 2010-03-15T11:03:36Z
This program compiles and runs with no errors, Don and Aldo Nunez think there are some inconcistancies here: void main() { static assert((cast(ushort)(-1.0L)) == 0xFFFF); static assert((cast(uint)(-1.0)) == 0); static assert((cast(uint)(-1.0L)) == 0); static assert((cast(ulong)(-1.0L)) == 0xbff0000000000000UL); assert((cast(ushort)(-1.0L)) == 0xFFFF); assert((cast(uint)(-1.0)) == 0); assert((cast(uint)(-1.0L)) == 0); assert((cast(ulong)(-1.0L)) == 0xbff0000000000000UL); } Don>The cast(uint) case is clearly a bug.<
Comment #1 by aldonunez1 — 2010-03-15T12:38:47Z
It seems like the runtime casting of (float, double, real -> uint) and (float, double -> ulong) can be done simpler, and in a way that would fix the -1.0 -> 0 bug. When converting from float or double to ulong; why can't it be done like real to ulong, where there is a simple conversion in x87 registers plus a fixup for ulong values greater than long.max? When converting from FP to uint; why can't it be done like FP to ushort, where there is a simple conversion to int with x87 registers, and then a truncation? This would make all floating point to integer conversions consistent, and get rid of this bug where an FP -1 turns into an integer 0xFF... in some cases, and in others 0. It should always be 0xFF..., just like a signed integer to unsigned conversion.
Comment #2 by clugdbug — 2013-01-07T09:07:42Z
This passes on Linux32 and 64, on 1.076 and 2.061. Also tested on D1.073 so it has been working for quite some time on Linux. Need to check if it is Windows-specific. void main() { static assert((cast(ushort)(-1.0)) == 0xFFFF); static assert((cast(ushort)(-1.0L)) == 0xFFFF); static assert((cast(uint)(-1.0)) == 0xFFFF_FFFF); static assert((cast(uint)(-1.0L)) == 0xFFFF_FFFF); static assert((cast(ulong)(-1.0L)) == 0xFFFF_FFFF_FFFF_FFFFUL); assert((cast(ushort)(-1.0)) == 0xFFFF); assert((cast(ushort)(-1.0L)) == 0xFFFF); assert((cast(uint)(-1.0)) == 0xFFFF_FFFF); assert((cast(uint)(-1.0L)) == 0xFFFF_FFFF); assert((cast(ulong)(-1.0L)) == 0xFFFF_FFFF_FFFF_FFFFUL); }
Comment #3 by simen.kjaras — 2013-01-07T11:02:17Z
Just tested on Windows. First two asserts and static asserts pass, the rest fail.
Comment #4 by safety0ff.bugz — 2013-11-06T17:36:10Z
Could be related to issue 9844, can somebody re-test on the affected platform(s)?
Comment #5 by bearophile_hugs — 2013-11-07T01:24:39Z
Now this passes on Windows32, I close down the issue: void main() { static assert((cast(ushort)(-1.0L)) == 0xFFFFU); static assert((cast(uint)(-1.0)) == 0xFFFF_FFFFU); static assert((cast(uint)(-1.0L)) == 0xFFFF_FFFFU); static assert((cast(ulong)(-1.0L)) == 0xFFFF_FFFF_FFFF_FFFFUL); assert((cast(ushort)(-1.0L)) == 0xFFFF); assert((cast(uint)(-1.0)) == 0xFFFF_FFFFU); assert((cast(uint)(-1.0L)) == 0xFFFF_FFFFU); assert((cast(ulong)(-1.0L)) == 0xFFFF_FFFF_FFFF_FFFFUL); }