Integer overflow handling on P3 vs. P4

  • Thread starter Thread starter Mikael Svenson
  • Start date Start date
M

Mikael Svenson

Sample code:

static void Main(string[] args)
{
double inf = 0.1 / 0.0;
int test2 = (int)(inf * 0.0F);
Console.WriteLine( test2.ToString() );
}

On a P3 this gives the result "0", on a P4 it gives -2147483648 which is
int.MinValue.

Anyone know why this happens? Is it .Net which compiled wrongly on a P4,
or is it the P4 which is erroneus?

Of course if I compile with overflow checking it throws an exception,
and it's good practise to check the value before you divide with it. (I
made this example out from a graph component I downloaded which failed
on a P4.)

Regards,
Mikael Svenson
 
surely either result is acceptable since either result is incorrect because
the answer is undefined.

why be too bothered about how processors divide zero when it's something
that should never occur?

LATER! =o)
Dan.

Sample code:

static void Main(string[] args)
{
double inf = 0.1 / 0.0;
int test2 = (int)(inf * 0.0F);
Console.WriteLine( test2.ToString() );
}

On a P3 this gives the result "0", on a P4 it gives -2147483648 which is
int.MinValue.

Anyone know why this happens? Is it .Net which compiled wrongly on a P4,
or is it the P4 which is erroneus?

Of course if I compile with overflow checking it throws an exception,
and it's good practise to check the value before you divide with it. (I
made this example out from a graph component I downloaded which failed
on a P4.)

Regards,
Mikael Svenson
 
I'm not that bothered :) but it is still interesting. And mathematically
0 should be the correct answer. We've also seen a strange rounding error
at work, where 2.24 becomes 2.2400000021. That's on a P4 as well.
Haven't tried it on a P3 yet. So could there possible be P4 bug ;)

-m
 
Mikael Svenson said:
I'm not that bothered :) but it is still interesting. And mathematically
0 should be the correct answer. We've also seen a strange rounding error
at work, where 2.24 becomes 2.2400000021.

I wouldn't be convinced that that's a rounding error until I'd seen
more details - see
http://www.pobox.com/~skeet/csharp/floatingpoint.html
That's on a P4 as well.
Haven't tried it on a P3 yet. So could there possible be P4 bug ;)

Actually, I don't think it's a bug. If you look at the C# language
specifications, 0.1/0.0 should be +infinity, and then
0*infinity should be NaN. The tricky bit is what the integer cast
should do. The ECMA spec (section 13.2.1) says (about double to integer
conversions):

<quote>
In an unchecked context, the conversion always succeeds, and proceeds
as follows:

If the value of the source operand is within the range of the
destination type, then it is rounded towards zero to the nearest
integral value of the destination type, and this integral value is the
result of the conversion.

Otherwise, the result of the conversion is an unspecified value of the
destination type.
</quote>

Now, as far as I can see, NaN *isn't* within the range of int, so the
result is an unspecified value - in other words, there's no wrong
answer.
 
Thanks for the answer :)

But it's still weird that the same binary produces different result on a
P3 and a P4 with the same Framework installed.

-m
 
Mikael Svenson said:
Thanks for the answer :)

But it's still weird that the same binary produces different result on a
P3 and a P4 with the same Framework installed.

Maybe - maybe not. It may well be something to do with how the NaNs are
stored in memory - there are many different potential bit patterns for
NaN, and it could well be that the P4 differentiates between different
NaNs more or less than the P3. Certainly an interesting thing to see
though :)
 
It's not always the case that you want to treat divide by zero as a special
case that your code should handle. In some cases (ray tracer geommetry, for
example), the INF result you get from dividing by zero is the desired result
and continues to function correctly in the calculations. So you can get a
decent speed up on a tight looped algorithm by removing a zero check.

Niall
 
The P4 has a totally new architecture for floating point (as well as some of
the P3 circuitry for the older instructions). I vaguely recall someone
asking about what SSE2 instructions the JIT uses, and the answer was that it
only uses them for casts and shifts or some such thing. This is a pretty
vague recollection, but if it's correct, it could explain the difference in
results, considering that SSE2 is new to the P4.

Niall
 
Back
Top