我讨厌不得不问这个,因为我认为答案必须简单,但我不能因为我的生活似乎追查来源。在尝试重写函数时遇到了这个问题:
a = -j
x = real(a)
y = imag(a)
y/x
对我来说意外地吐出了Inf
。然而...
a = 0
b = -1
b/a
像我期望的那样返回-Inf
。进一步询问,a == x
,b == y
。显然,这不是真的。经过很多挫折后,我终于找到了问题。如果a
的原始输入改为0-j
(而不是-j
),那么就没有问题。
real(-j)
和real(0-j)
都返回零并测试为零,但显然似乎保留了一些与其来源无关的元数据,我绝对无法发现。我到底错过了什么?如果我必须用if (x == 0) then x = 0;
答案 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):
瞧!在MATLAB中也是-0 exists!
答案 1 :(得分:1)
当使用IEEE 754浮点数时,有一个约定接近零的约定,这个数字不能用称为下溢的最小可能浮点表示,其中数字的精度在每个步骤低于最小浮点数时丢失。一些操作系统会认为下溢等于零。
我很惊讶地测试了一些软件并发现零阈值测试实际上已经低于零,几乎可以达到最小可能的负浮动。
也许这就是为什么你得到一个负无穷大而不是零除错误,我假设是你所指的问题。