对于Matlab中的向量,uint64并不精确

时间:2016-01-04 12:50:07

标签: matlab

我在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

这是我问这个问题的根本原因。我很难看到这种情况的解决方法。

3 个答案:

答案 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。