Jump to page: 1 2
Thread overview
[Issue 9937] New: CTFE floats don't overflow correctly
Apr 16, 2013
Don
Apr 16, 2013
Walter Bright
Apr 18, 2013
Don
Apr 18, 2013
Walter Bright
Apr 19, 2013
Don
Apr 19, 2013
Walter Bright
Apr 22, 2013
Don
Apr 22, 2013
Walter Bright
Apr 23, 2013
Don
Apr 23, 2013
Don
Apr 24, 2013
Walter Bright
Apr 24, 2013
Don
Apr 24, 2013
Walter Bright
Apr 25, 2013
Don
Apr 25, 2013
Walter Bright
Apr 26, 2013
Don
Aug 02, 2013
yebblies
Aug 22, 2013
Don
April 16, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9937

           Summary: CTFE floats don't overflow correctly
           Product: D
           Version: D1 & D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody@puremagic.com
        ReportedBy: clugdbug@yahoo.com.au


--- Comment #0 from Don <clugdbug@yahoo.com.au> 2013-04-16 04:14:56 PDT ---
This should pass. The multiply by 2 must cause an infinity, at least when x is stored.
---
int blah()
{
    float x = float.max;
    x *= 2;
    x /= 2;
    assert(x == float.infinity);
    return 1;
}

static assert(blah());
---

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 16, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9937


Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |bugzilla@digitalmars.com
         Resolution|                            |INVALID


--- Comment #1 from Walter Bright <bugzilla@digitalmars.com> 2013-04-16 11:58:22 PDT ---
I'm going to disagree.

In D, any floating point algorithm that relies on a maximum precision is broken. The compiler and runtime is allowed to do all such calculations at as high a precision as they want to - the types only specify a minimum precision, not a maximum.

This is unlike C, which requires a maximum precision upon assignment.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 18, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9937


Don <clugdbug@yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |REOPENED
         Resolution|INVALID                     |


--- Comment #2 from Don <clugdbug@yahoo.com.au> 2013-04-18 03:32:03 PDT ---
> In D, any floating point algorithm that relies on a maximum precision is
broken. The compiler and runtime is allowed to do all such calculations at as high a precision as they want to - the types only specify a minimum precision, not a maximum.

That's not exactly true. It's true that the intermediate results may be at
extended precision, for example, it would not be true that
    float x = float.max;
    assert( (x * 2) / 2 == float.infinity); // may fail

But float and double must be IEEE types.
Without this, it's impossible to write correct floating-point code.
The big problem here is that the CTFE behaviour is different to the runtime
behaviour.

I hit this with HalfFloat, I can't implement it correctly because of this issue.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 18, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9937



--- Comment #3 from Walter Bright <bugzilla@digitalmars.com> 2013-04-18 13:42:16 PDT ---
You're correct for C, as those are the C rules. But this is not true for D.

Can you be more specific about what you're doing in CTFE that does not work?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 19, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9937



--- Comment #4 from Don <clugdbug@yahoo.com.au> 2013-04-19 00:57:55 PDT ---
(In reply to comment #3)
> You're correct for C, as those are the C rules. But this is not true for D.
> 
> Can you be more specific about what you're doing in CTFE that does not work?

Define an IEEE single-precision floating-point constant. Perhaps this is a better example:

void main()
{
         float f1 = float.max * 2;
   const float f2 = float.max * 2;
   assert(f1 == float.infinity);          // ok
   assert(f1 == f2);                      // ok
   assert(*&f2 == float.infinity);        // even this is OK
   assert(f2 == float.infinity);          // fails!!!!!!!!!!!!!!!!!
}

f2 apparently has two different values at the same time!

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 19, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9937



--- Comment #5 from Walter Bright <bugzilla@digitalmars.com> 2013-04-19 13:26:17 PDT ---
Yes, having a runtime computation be different from a compile time computation is a potential result of doing floating point math at higher precision at compile time.

However, this is as designed and is expected.

It is a programming error in D to rely on limited precision. The only time I've seen legitimate code that relied on limited precision is as part of a test suite - i.e. not a real application.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 22, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9937



--- Comment #6 from Don <clugdbug@yahoo.com.au> 2013-04-22 08:23:35 PDT ---
(In reply to comment #5)
> Yes, having a runtime computation be different from a compile time computation is a potential result of doing floating point math at higher precision at compile time.
> 
> However, this is as designed and is expected.
> 
> It is a programming error in D to rely on limited precision. The only time I've seen legitimate code that relied on limited precision is as part of a test suite - i.e. not a real application.

Are you sure your recognized it? I've written very little floating point code that didn't! Cephes relies on it, for example.

It's not difficult to cope with x87 using C's semantics, but this is not at all the same as saying that you can add extra bits of precision *anywhere* without impact.

It is impossible to generate correct results in the lowest bit, without knowing
the target precision. Otherwise you get double rounding.
I think this can be proved mathematically.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 22, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9937



--- Comment #7 from Walter Bright <bugzilla@digitalmars.com> 2013-04-22 13:00:12 PDT ---
I'd like to see an example of code that produces less accurate results if it had more precision.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 23, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9937



--- Comment #8 from Don <clugdbug@yahoo.com.au> 2013-04-22 23:44:17 PDT ---
There's a nice discussion here:

http://www.exploringbinary.com/double-rounding-errors-in-floating-point-conversions/

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 23, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9937



--- Comment #9 from Don <clugdbug@yahoo.com.au> 2013-04-23 04:46:04 PDT ---
And a real-world example, of where it caused a vulnerability in both Java and PHP.

http://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
« First   ‹ Prev
1 2