我在Matlab中使用向量时发现了uint64
的不一致。似乎uint64的数组并不是所有64位的精确数组。这没有给出我预期的输出,
p=uint64([0;0]);
p(1)=13286492335502040542
p =
13286492335502041088
0
然而
q = uint64(13286492335502040542)
q =
13286492335502040542
一样。它也在与
合作p(1)=uint64(13286492335502040542)
p =
13286492335502040542
0
使用无符号整数时,人们期望一种特殊的行为,通常也是完美的精度。这看起来很怪异甚至有点不可思议。我没有用较小的数字看到这个问题。也许有人知道更多?我不认为这是一个未知的问题,所以我想必须有一些解释。我很高兴知道为什么会发生这种情况以及什么时候能够避免它。像往常一样,文档中没有提到这种问题。
Matlab 2014a,Windows 7。
修改
值得一提的是,在直接定义数组时,我可以看到相同的行为。
p=uint64([13286492335502040542;13286492335502040543])
p =
13286492335502041088
13286492335502041088
这是我问这个问题的根本原因。我很难看到这种情况的解决方法。
答案 0 :(得分:10)
虽然这可能令人惊讶,但这是一个浮点精度问题。 : - )
问题是,MATLAB中默认情况下所有数字文字都是double
类型;这就是原因:
13286492335502040542 == 13286492335502041088
将返回true
; 13286492335502040542
的双精度浮点表示为13286492335502041088
。由于p
具有类uint64
,因此对其执行的所有赋值都会将右侧投射到其类中。
另一方面,uint64(13286492335502040542)
"呼叫"将由MATLAB解释器进行优化,以避免为uint64
参数调用double
函数的开销,并将文字直接转换为其无符号整数表示(这是精确的)。
在第三方面[原文如此],函数调用优化并不适用于
p = uint64([13286492335502040542;13286492335502040543])
因为uint64
的参数不是文字,而是表达式的结果,即vertcat
运算符应用于两个double
个操作数的结果。在这种情况下,MATLAB解释器不够智能,无法确定两个函数调用应该"通勤" (uint的连接应该与连接的uint相同),因此它评估连接(由于FP精度,它给出了一个等于double
的数组),然后将两个相似的double
值转换为{{ 1}}。
TLDR:
之间的区别uint64
和
p = uint64(13286492335502040542);
是函数调用优化的副作用。
答案 1 :(得分:7)
Matlab,除非另有说明,否则将数字读为double,然后转换为相关的数据类型。 Matlab double数据类型允许浮点分数为51位,从而可以存储52位整数而不会丢失预占位(尾数)。请注意,13286492335502041088
只是13286492335502040543
,最后12位设置为零。
正如您所说,解决方案是直接转换文字uint64(13286492335502040543)
。
p=uint64([13286492335502040542;13286492335502040543])
不起作用,因为它会创建一个双数组,然后将其转换为uint64
uint64文档中的“更多关于”中提到了此问题,但未提及除非另有说明,否则横向读取为双精度。
答案 2 :(得分:0)
我同意这看起来很奇怪,我没有解释。我有一个解决方法:
p=[uint64(13286492335502040542);uint64(13286492335502040543)]
即,将单独的值转换为uint64
s。