Question

I hate having to ask this because I assume the answer must be simple, but I cannot for the life of me seem to track down the source. While trying to rewrite a function I ran across this problem:

a = -j
x = real(a)  
y = imag(a)
y/x

Which spits out Inf, unexpectedly for me. However...

a = 0
b = -1
b/a

returns -Inf, like I would expect. Inquiring further, a == x, b == y. Clearly that isn't true however. I finally tracked down the problem to this after a lot of frustration. If the original input for a is instead 0-j (vs. -j) then there is no problem.

Both real(-j) and real(0-j) return zero and test as zero, but obviously seem to retain some metadata relating to their origin that I absolutely cannot discover. What precisely am I missing here? It will feel downright wrong if I have to solve this with something like if (x == 0) then x = 0;

Was it helpful?

Solution

Not metadata, just the sign bit of the double precision float.

>> a = 0-j;
>> b = -j;
>> ra = real(a)
ra =
     0
>> rb = real(b)
rb =
     0
>> ra==0
ans =
     1
>> isequal(ra,rb)
ans =
     1

Looks the same so far. However, the difference is that with b, we set the sign bit for both the real and imaginary parts when we do -j = -complex(0,1) vs. 0-j = complex(0,-1) (see Creating Complex Numbers). Looking deeper with typecast, which does no conversion of the underlying data:

>> dec2bin(typecast(ra,'uint64'),64)
ans =
0000000000000000000000000000000000000000000000000000000000000000
>> dec2bin(typecast(rb,'uint64'),64)
ans =
1000000000000000000000000000000000000000000000000000000000000000

That 1 is bit 63 (of 0) in the IEEE 754 double precision floating point representation:

enter image description here

Voila! -0 exists in MATLAB too!

OTHER TIPS

When using IEEE 754 floating point numbers there is a convention to have a number approaching zero that cannot be represented by the smallest possible float called an underflow where the precision of the number is being lost with each step below the smallest possible float. Some operating systems will consider the underflow to be equal to zero.

I was surprised to be testing some software and find that a threshold test of zero actually went below zero almost as far as the smallest possible negative float.

Perhaps this is why your getting a negative infinity instead of a divide by zero error which I am assuming is the problem your referring to.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top