Thread overview
[Issue 3171] New: % not implemented correctly for floats
Jul 13, 2009
Walter Bright
Jul 14, 2009
Don
Jul 14, 2009
Walter Bright
Jul 14, 2009
Don
Jul 14, 2009
Walter Bright
Dec 06, 2009
Walter Bright
July 13, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3171

           Summary: % not implemented correctly for floats
           Product: D
           Version: unspecified
          Platform: Other
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody@puremagic.com
        ReportedBy: andrei@metalanguage.com


Pasting a posting from Walter in digitalmars.d:

Hmm, I just noticed that the code generator should use FPREM1 instead to get IEEE conformance. Darn.

http://www.sesp.cse.clrc.ac.uk/html/SoftwareTools/vtune/users_guide/mergedProjects/analyzer_ec/mergedProjects/reference_olh/mergedProjects/instructions/instruct32_hh/vc108.htm

http://www.sesp.cse.clrc.ac.uk/html/SoftwareTools/vtune/users_guide/mergedProjects/analyzer_ec/mergedProjects/reference_olh/mergedProjects/instructions/instruct32_hh/vc109.htm

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
July 13, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3171


Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bugzilla@digitalmars.com




--- Comment #1 from Walter Bright <bugzilla@digitalmars.com>  2009-07-13 13:08:41 PDT ---
As to why the code generator doesn't use FPREM1 instead of FPREM, there's the
following comment: "We don't use fprem1 because for some inexplicable
reason we get -5 when we do _modulo(15, 10)"

This could be a bug in older CPUs.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
July 14, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3171


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

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |clugdbug@yahoo.com.au




--- Comment #2 from Don <clugdbug@yahoo.com.au>  2009-07-14 01:49:30 PDT ---
(In reply to comment #1)
> As to why the code generator doesn't use FPREM1 instead of FPREM, there's the
> following comment: "We don't use fprem1 because for some inexplicable
> reason we get -5 when we do _modulo(15, 10)"
> 
> This could be a bug in older CPUs.

It isn't a bug. That's what the IEEE remainder specifies. Note that C's fmod is NOT the same as IEEE remainder.

15/10 = 1.5, so there's a choice of n == 1 or n==2. The standard specifies even n in such cases, so r == a - b*n == 15 - 2*10 == -5.

That's kind of... weird, highly non-intuitive, and not terribly useful. I'm pretty sure that that behaviour would be unpopular.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
July 14, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3171





--- Comment #3 from Walter Bright <bugzilla@digitalmars.com>  2009-07-14 02:27:46 PDT ---
Thanks for the explanation. At least I know why that happens, now. What do you suggest, then? Staying with FPREM or going with FPREM1 ?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
July 14, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3171





--- Comment #4 from Don <clugdbug@yahoo.com.au>  2009-07-14 04:03:19 PDT ---
(In reply to comment #3)
> Thanks for the explanation. At least I know why that happens, now. What do you suggest, then? Staying with FPREM or going with FPREM1 ?

It's hard to justify including a primitive built-in operator that differs from IEEE. But it may be justifiable when it's the only way to avoid a major break from C and intuition.

  int x = 15 % 10;
  int y = cast(int)((cast(float)15) % 10);

// Are we really comfortable with these being completely different?

You know, all this time I was thinking that the behaviour of % for negative integers was because it needed to be consistent with floating-point modulus... Now it just seems to be wrong.


But I think I have the answer. In IEEE, the preferred conversion from float to int uses round-to-nearest. IEEE remainder makes sense in that context. Since in cast(int), D has inherited 'chop' rounding from C, D needs to also inherit C's fmod behaviour.

So D should stay with FPREM. But we need to document it properly.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
July 14, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3171





--- Comment #5 from Walter Bright <bugzilla@digitalmars.com>  2009-07-14 15:15:10 PDT ---
We're not breaking with C because C has no % operator for floats. But I agree we should match C99's fmod behavior, which is its current behavior.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 06, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3171


Walter Bright <bugzilla@digitalmars.com> changed:

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


--- Comment #6 from Walter Bright <bugzilla@digitalmars.com> 2009-12-06 00:46:11 PST ---
Fixed dmd 1.053 and 2.037

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------