You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@harmony.apache.org by Ian Rogers <ia...@manchester.ac.uk> on 2009/06/24 12:08:35 UTC

Re: [luni] Math.max(double, double) gives wrong answer when Math.max(-0.0d, 0.0d) (HARMONY-6242)

2009/6/24 Tim Ellison <t....@gmail.com>:
> I love these ;-)
>
> Ian Rogers (JIRA) wrote:
>> Math.max(double, double) gives wrong answer when Math.max(-0.0d, 0.0d)
>> ----------------------------------------------------------------------
>>
>>                  Key: HARMONY-6242
>>                  URL: https://issues.apache.org/jira/browse/HARMONY-6242
>>              Project: Harmony
>>           Issue Type: Bug
>>           Components: Classlib
>>     Affects Versions: 5.0M10
>>          Environment: Any, my test environment is x64 Linux with MRP (http://mrp.codehaus.org/)
>>             Reporter: Ian Rogers
>>              Fix For: 5.0M11
>>
>>
>> In the code:
>>
>> public static double max(double d1, double d2) {
>>   if (d1 > d2)
>>     return d1;
>>   if (d1 < d2)
>>     return d2;
>>   /* if either arg is NaN, return NaN */
>>   if (d1 != d2)
>>     return Double.NaN;
>>   /* max( +0.0,-0.0) == +0.0 */
>>   if (d1 == 0.0 && (d1 != -0.0d || d2 != -0.0d))
>>     return 0.0;
>>   return d1;
>> }
>>
>> This test is never true:
>>
>>   if (d1 == 0.0 && (d1 != -0.0d || d2 != -0.0d))
>>
>> as 0.0 == -0.0 and d2 must be 0.0 or -0.0. This means that in the case of two 0.0 parameters d1 is returned, which is the incorrect behaviour if d2 is 0.0 and d1 -0.0.
>>
>> A simple test:
>>
>>       System.out.println(Math.max(-0.0d, 0.0d));
>>
>> prints -0.0 with Harmony and 0.0 with a non-Harmony classlib.
>>
>
> So is the answer to replace the last test with:
>
>  if (Double.doubleToRawLongBits(d1) == Double.doubleToRawLongBits(-0.0d)) {
>      return d2;
>  }
>  return d1;

I think there are plenty of ways to write it, you could compare
against the raw long bits of d2. In your code you could just return
0.0d rather than d1 at the end which may expose some constant
propagation. I was wondering if for Intel SSE there'd be some way to
optimize this to use the MAXSS/MAXSD instructions.

Regards,
Ian

> Regards,
> Tim
>

Re: [luni] Math.max(double, double) gives wrong answer when Math.max(-0.0d, 0.0d) (HARMONY-6242)

Posted by Tim Ellison <t....@gmail.com>.
Ian Rogers wrote:
> 2009/6/24 Tim Ellison <t....@gmail.com>:
>> I love these ;-)
>>
>> Ian Rogers (JIRA) wrote:
<snip>
>>> A simple test:
>>>
>>>       System.out.println(Math.max(-0.0d, 0.0d));
>>>
>>> prints -0.0 with Harmony and 0.0 with a non-Harmony classlib.
>>>
>> So is the answer to replace the last test with:
>>
>>  if (Double.doubleToRawLongBits(d1) == Double.doubleToRawLongBits(-0.0d)) {
>>      return d2;
>>  }
>>  return d1;
> 
> I think there are plenty of ways to write it, you could compare
> against the raw long bits of d2. In your code you could just return
> 0.0d rather than d1 at the end which may expose some constant
> propagation. I was wondering if for Intel SSE there'd be some way to
> optimize this to use the MAXSS/MAXSD instructions.

I committed a fix for the incorrect behavior at r787977, if there are
optimizations we can look at those too.

Thanks,
Tim