变量包含额外的隐藏元数据 - 也就是当零不为零(但仍然是)

时间:2014-03-01 02:49:48

标签: matlab floating-point complex-numbers zero

我讨厌不得不问这个,因为我认为答案必须简单,但我不能因为我的生活似乎追查来源。在尝试重写函数时遇到了这个问题:

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

对我来说意外地吐出了Inf。然而...

a = 0
b = -1
b/a

像我期望的那样返回-Inf。进一步询问,a == xb == y。显然,这不是真的。经过很多挫折后,我终于找到了问题。如果a的原始输入改为0-j(而不是-j),那么就没有问题。

real(-j)real(0-j)都返回零并测试为零,但显然似乎保留了一些与其来源无关的元数据,我绝对无法发现。我到底错过了什么?如果我必须用if (x == 0) then x = 0;

之类的东西来解决这个问题,那将会感到完全错误

2 个答案:

答案 0 :(得分:10)

不是元数据,只是双精度浮点数的符号位。

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

到目前为止看起来一样。但是,与b不同的是,当我们执行-j = -complex(0,1)0-j = complex(0,-1)时,我们会为实部和虚部设置符号位(请参阅Creating Complex Numbers)。深入了解typecast,它不会转换基础数据:

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

{1>是IEEE 754 double precision floating point表示中的第63位(0):

enter image description here

瞧!在MATLAB中也是-0 exists

答案 1 :(得分:1)

当使用IEEE 754浮点数时,有一个约定接近零的约定,这个数字不能用称为下溢的最小可能浮点表示,其中数字的精度在每个步骤低于最小浮点数时丢失。一些操作系统会认为下溢等于零。

我很惊讶地测试了一些软件并发现零阈值测试实际上已经低于零,几乎可以达到最小可能的负浮动。

也许这就是为什么你得到一个负无穷大而不是零除错误,我假设是你所指的问题。