0.0 / 0.0 = -NAN ?

16 views
Skip to first unread message

Skybuck Flying

unread,
Apr 30, 2022, 11:31:04 AMApr 30
to
When exception masks are all enabled to stop the processor from throwing floating point exceptions the following calculation produces a somewhat strange result:

0.0 / 0.0 = -nan

(At least in Delphi).

For now I will assume this is the case in C/C++ as well and with that I mean on x86/x64 which should and seems to be following IEEE 754 floating-point format.

I am a little bit surprised by this and I want/need to know more. Where is this defined that 0.0 / 0.0 should be -NAN ?!?

Problem is with the code, example:

T := 0;
D := 0.0 / 0.0;
P := T * D;

This screws up P. instead of P being zero, P is now also -NAN ?!?

I find this very strange but ok.

I guess a simple solution could be to set D to 0 explicitly for this case, is there perhaps another solution ? Maybe some kind of mask or rounding mode so that additional branch is not necessary ???

Bye for now,
Skybuck.

Skybuck Flying

unread,
Apr 30, 2022, 1:37:00 PMApr 30
to
In delphi it even depends on the platform.

Win32: 0.0 / 0.0 = -NAN
Win64: 0.0 / 0.0 = -1, #IND

Win32 sets FPU exception mask
Win64 sets SSE exception mask

(I believe I read somewhere that there are slight differences in FPU vs SSE floating point operations, but can't recall right now... something to maybe further look into... for now my tests have shown that the code I am working on currently works on both platforms...)

Just to be clear 0.0 for me at least simply means a 0 floating point number.

Though there is also +0.0 and -0.0 I think... and also -Infinity and +Infinity.

I would like to find some kind of specification or definition that goes deeper/explains why 0/0 produces these values ?!

Also these values seem to be "infectious" like a virus lol, it seems to be "propagated" through operations, so far multiplication, addition and comparison have been observed/witnessed ! ;)

Bye for now,
Skybuck.

P.S.: Keep your floating point issues out of my computer programs ! =D (Will SmITH meme =D)

Herbert Kleebauer

unread,
Apr 30, 2022, 3:02:13 PMApr 30
to
On 30.04.2022 17:31, Skybuck Flying wrote:

> When exception masks are all enabled to stop the processor from > throwing floating point exceptions the following calculation
> produces a somewhat strange result:
>
> 0.0 / 0.0 = -nan

Why is this strange? 0/0 is undefined and therefore "Not A Number"


> Problem is with the code, example:
>
> T := 0;
> D := 0.0 / 0.0;
> P := T * D;
>

Why should P be zero? Suppose T=x and D=x/x^2
For x=0 you get T=0, D=0/0 and you say P should be 0,
but P=T*D = x*x/x^2 = 1


> This screws up P. instead of P being zero, P is now also -NAN ?!?

"Something" multiplied with "NotANumber" is also "NotANumber" even if the
"something" is zero.

Alexei A. Frounze

unread,
Apr 30, 2022, 7:25:38 PMApr 30
to
On Saturday, April 30, 2022 at 8:31:04 AM UTC-7, Skybuck Flying wrote:
> When exception masks are all enabled to stop the processor from throwing floating point exceptions the following calculation produces a somewhat strange result:
>
> 0.0 / 0.0 = -nan

Totally expected. 0 / 0 is undefined. This should've been covered in middle school.

> (At least in Delphi).
>
> For now I will assume this is the case in C/C++ as well and with that I mean on x86/x64 which should and seems to be following IEEE 754 floating-point format.
>
> I am a little bit surprised by this and I want/need to know more. Where is this defined that 0.0 / 0.0 should be -NAN ?!?
>
> Problem is with the code, example:
>
> T := 0;
> D := 0.0 / 0.0;
> P := T * D;
>
> This screws up P. instead of P being zero, P is now also -NAN ?!?

What you're seeing is on purpose and by design.
Suppose you had sqrt(-1e-30) in place of 0/0, that is, your
computations had some rounding errors and the square root
got a negative argument instead of zero or a small positive argument.
If we're staying away from complex values, square root of
negative argument is undefined as well.

But the CPU doesn't know that it may, for example, ignore this error
in the context of your formula and simply substitute 0 for sqrt(-1e-30).
So, instead it returns a NAN for sqrt(-1e-30) and poisons with it
all further computations by propagating the NAN all the way through
all operations to the final result.

This way the programmer may find out that their result had an
anomaly during computation and something needs to be done with it.

You can also think of it in terms of "how do I hide a boolean or
an if statement in a pure math formula/expression". This is how.

Alex

wolfgang kern

unread,
May 1, 2022, 6:10:50 AMMay 1
to
On 30/04/2022 17:31, Skybuck Flying wrote:
> When exception masks are all enabled to stop the processor from throwing floating point exceptions the following calculation produces a somewhat strange result:
>
> 0.0 / 0.0 = -nan

[...]
divide any number by zero is prohibited by math laws anyway because it
cannot produce other result then philosophical plus/minus infinitive.
And also 0/0 is not 1 of course.
__
wolfgang

Skybuck Flying

unread,
May 1, 2022, 10:19:36 PMMay 1
to
I discovered another dangerous one while trying to compute overlap of interval (basically ranges) and/or trying to clip/cap line segments:

0 * +infinity = -NAN

This happens as the ray is on the edge of a boundary/box... cause tMinX will become -NAN.

Leading to weird situations depending on how the code was written, either the wrong point will be taken or it will not clip at all.

Once intersection segment with ray and box has been calculated, the ray segment has to be checked against the interestion segment to check if it overlaps... it's still possible it does not overlap.. for a "ray segment box intersection" algorithm. Analog to "line triangle intersection" algorithm, first "line plane intersection" then check if intersection point lies inside triangle which lies inside the plane.

I have seen some papers that try and work around these issues at least for ray/box intersection, but if these tricks work for ray segment box intersection remains to be seen.

Anyway best way to solve it is to use custom code for when delta x, y, or z is zero... instead of trying to divide or multiply by zero and infinity and such things cause certain combinations can lead to -NAN problems. Also win32 and win64 behave differently in delphi somewhat... perhaps 0 * infinity produces something else in win64... not yet sure...

It's in my video which I will upload shortly... hmmm...

Anyway... I am leaving math hell for now... leaving fpu hell... and returning back to the surface ! =D

Bye,
Skybuck =D

wolfgang kern

unread,
May 2, 2022, 3:42:19 AMMay 2
to
On 02/05/2022 04:19, Skybuck Flying wrote:
...
> Anyway... I am leaving math hell for now... leaving fpu hell... and returning back to the surface ! =D

now at least we see one wise decision from you (for the first time).
Yeah, let those who got a working brain handle logic and math!
__
wolfgang

Kerr-Mudd, John

unread,
May 2, 2022, 4:55:18 AMMay 2
to
He also has trouble noticing that this is an asm, not Delphi, NG.

--
Bah, and indeed Humbug.
Reply all
Reply to author
Forward
0 new messages