Thread overview
[Bug 45] New: Bug in conversion of floating point literals
Mar 13, 2006
d-bugmail
Mar 15, 2006
Thomas Kuehne
Mar 15, 2006
d-bugmail
Mar 15, 2006
Thomas Kuehne
Mar 16, 2006
d-bugmail
Apr 11, 2006
d-bugmail
March 13, 2006
http://d.puremagic.com/bugzilla/show_bug.cgi?id=45

           Summary: Bug in conversion of floating point literals
           Product: D
           Version: 0.149
          Platform: PC
        OS/Version: Windows
            Status: NEW
          Severity: critical
          Priority: P2
         Component: DMD
        AssignedTo: bugzilla@digitalmars.com
        ReportedBy: clugdbug@yahoo.com.au


Literals are treated (incorrectly) as type real when used in an initialiser, but as type double when used in an assignment. This is an extremely difficult bug to track down, as it is essentially bad code generation, so I've marked it as critical.

void main()
{
    real a = 3.40483; // this is treated as 3.40483L
    real b;
    b = 3.40483;
    assert(a==b);
}


-- 

March 15, 2006
d-bugmail@puremagic.com schrieb am 2006-03-13:
> Literals are treated (incorrectly) as type real when used in an initialiser, but as type double when used in an assignment. This is an extremely difficult bug to track down, as it is essentially bad code generation, so I've marked it as critical.
>
> void main()
> {
>     real a = 3.40483; // this is treated as 3.40483L
>     real b;
>     b = 3.40483;
>     assert(a==b);
> }

Strictly speaking the code above behaves correctly.

http://www.digitalmars.com/d/float.html
# For floating point operations and expression intermediate values, a
# greater precision can be used than the type of the expression. Only the
# minimum precision is set by the types of the operands, not the maximum.

The documentation doesn't require an expression to always use the same "excessive" precision.

Never the less, the shown behaviour is annoying - either expand the literal's precision on all ocasion or never.

Thomas


March 15, 2006
http://d.puremagic.com/bugzilla/show_bug.cgi?id=45





------- Comment #2 from clugdbug@yahoo.com.au  2006-03-15 06:12 -------
> Strictly speaking the code above behaves correctly.
> 
> http://www.digitalmars.com/d/float.html
> # For floating point operations and expression intermediate values, a
> # greater precision can be used than the type of the expression. Only the
> # minimum precision is set by the types of the operands, not the maximum.
> 
> The documentation doesn't require an expression to always use the same "excessive" precision.

That doesn't apply in this case. There's no intermediate value here.

3.40483L is not the same as 3.40483. It's a different number.

You provide the compiler with input values of a given precision, and it returns output values of a different precision. It's free to use any higher precision during the intermediate calculations, but it is NOT free to change the precision of the inputs (if it were, the L prefix would be entirely meaningless). It's just a bug (and I suspect it's a regression introduced during the improvements to constant folding that occurred around DMD 0.138).


-- 

March 15, 2006
d-bugmail@puremagic.com schrieb am 2006-03-15:
>> Strictly speaking the code above behaves correctly.
>> 
>> http://www.digitalmars.com/d/float.html
>> # For floating point operations and expression intermediate values, a
>> # greater precision can be used than the type of the expression. Only the
>> # minimum precision is set by the types of the operands, not the maximum.
>> 
>> The documentation doesn't require an expression to always use the same "excessive" precision.
>
> That doesn't apply in this case. There's no intermediate value here.
>
> 3.40483L is not the same as 3.40483. It's a different number.
>
> You provide the compiler with input values of a given precision, and it returns output values of a different precision. It's free to use any higher precision during the intermediate calculations, but it is NOT free to change the precision of the inputs (if it were, the L prefix would be entirely meaningless). It's just a bug (and I suspect it's a regression introduced during the improvements to constant folding that occurred around DMD 0.138).

I'm deffinatly on the "literal defines precision" side, but have a look
at:
http://d.puremagic.com/bugzilla/show_bug.cgi?id=21

Thomas



March 16, 2006
http://d.puremagic.com/bugzilla/show_bug.cgi?id=45





------- Comment #4 from clugdbug@yahoo.com.au  2006-03-16 02:16 -------
(In reply to comment #3)
> I'm deffinatly on the "literal defines precision" side, but have a look
> at:
> http://d.puremagic.com/bugzilla/show_bug.cgi?id=21

In his reply to that comment, Walter states:
"D always tries to do any compile time evaluation of floating
point constants at max precision."

That's perfectly reasonable, too. But it means that there's still a bug, but it's a different one now: floating point constants are not evaluated at max precision in assignment statements. But there's definitely something weird going on. Apparently, const double doesn't exist.

const float f = real.max;
real r = f;

This sets r = real.max. That's incredible, because a number that large cannot be stored in a float. If this behaviour is to remain, then 'const float' and 'const double' should be removed from the language, along with the 'f' and 'L' suffixes : all floating point constants are real.

However,

real r2;
r2 = f;

sets r2 = real.inf, which is what I would expect - real.max can't be stored in a float, so it became an infinity.


-- 

April 11, 2006
http://d.puremagic.com/bugzilla/show_bug.cgi?id=45


bugzilla@digitalmars.com changed:

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




------- Comment #5 from bugzilla@digitalmars.com  2006-04-11 01:31 -------
Fixed 0.153


--