我发现uint64
在Matlab中使用向量时存在不一致性.似乎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
这就是我问这个问题的根本原因.我很难看到这种情况的解决方法.
虽然这可能令人惊讶,但这是一个浮点精度问题.:-)
问题是,所有数字文字默认都是double
MATLAB中的类型; 这就是为什么:
13286492335502040542 == 13286492335502041088
会回来true
; 双精度的浮点表示13286492335502040542
是13286492335502041088
.由于p
有了类uint64
,所有完成的任务都会将右侧投射到它的类.
另一方面,uint64(13286492335502040542)
MATLAB解释器将优化"调用"以避免uint64
为double
参数调用函数的开销,并将文字直接转换为其无符号整数表示(这是精确的).
在第三方面[原文如此],函数调用优化不适用于
p = uint64([13286492335502040542;13286492335502040543])
因为参数uint64
不是文字,而是表达式的结果,即vertcat
运算符应用于两个double
操作数的结果.在这种情况下,MATLAB解释器不够聪明,无法确定两个函数调用应该"通勤"(uint的连接应该与连接的uint相同),因此它会评估连接(这给出了一个相等的数组,double
因为FP精度),然后将两个相似的double
值转换为uint64
.
TLDR:之间的区别
p = uint64(13286492335502040542);
和
u = 13286492335502040542; p = uint64(u);
是函数调用优化的副作用.
Matlab,除非另有说明,否则将数字读为double,然后转换为相关的数据类型.Matlab 双数据类型允许浮点分数为51位,从而可以存储52位整数而不会丢失预占位(尾数).请注意,13286492335502041088
只是13286492335502040543
设置为零的最后12位.
正如你所说,解决方案是直接转换文字uint64(13286492335502040543)
.
p=uint64([13286492335502040542;13286492335502040543])
不起作用,因为它创建一个双数组,然后将其转换为uint64
uint64文档中提到了这个问题,在"更多关于"下,虽然它没有提到除非另有说明,否则将被视为双精度.