uint64对于Matlab中的向量不完全正确 [英] uint64 is not exact for vectors in Matlab

查看:162
本文介绍了uint64对于Matlab中的向量不完全正确的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Matlab中使用向量时发现了uint64的不一致之处.似乎uint64数组并非对所有64位都是精确的.这没有给出我期望的输出,

I have discovered an inconsistency for uint64 when using vectors in Matlab. It seems as an array of uint64 is not exact for all 64 bits. This did not give the output I expected,

p=uint64([0;0]);
p(1)=13286492335502040542
p =
 13286492335502041088
                    0

但是

q = uint64(13286492335502040542)
q =
 13286492335502040542

确实.它也正在与

p(1)=uint64(13286492335502040542)
p =
 13286492335502040542
                    0

使用无符号整数,人们期望一种特殊的行为,并且通常还具有完美的精度.这看起来很奇怪,甚至有点不可思议.我看不到较小的数字会出现此问题.也许有人知道更多?我不希望这是一个未知的问题,所以我想必须对此有一些解释.我很想知道为什么会发生这种情况,何时才能避免这种情况发生.像往常一样,此类问题在文档中没有提到.

Working with unsigned integers one expect a special behaviour and usually also perfect precision. This seems weird and even a bit uncanny. I do not see this problem with smaller numbers. Maybe anyone knows more? I do not expect this to be an unknown problem, so I guess there must be some explanation to it. I would be good to know why this happen and when, to be able to avoid it. As usual this kind of issues is mentioned nowhere in the documentation.

Matlab 2014a,Windows 7.

Matlab 2014a, windows 7.

编辑

值得一提的是,直接定义数组时,我可以看到相同的行为.

It is worth mentioning that I can see the same behaviour when defining arrays directly.

p=uint64([13286492335502040542;13286492335502040543])
p =
 13286492335502041088
 13286492335502041088

这就是为什么我问这个问题的根源.对于这种情况,我很难看到解决方法.

This is the root to why I ask this question. I have hard to see workaround for this case.

推荐答案

虽然令人惊讶,但这是一个浮点精度问题. :-)

While it might be surprising, this is a floating point precision issue. :-)

问题是,在MATLAB中,所有数字文字默认情况下都是double类型;这就是为什么:

The thing is, all numeric literals are by default of type double in MATLAB; that's why:

13286492335502040542 == 13286492335502041088

将返回true; 13286492335502040542的双精度浮点表示形式是13286492335502041088.由于p具有类uint64,因此对它进行的所有赋值都会在其类的右侧进行投射.

will return true; the floating point representation in double precision of 13286492335502040542 is 13286492335502041088. Since p has the class uint64, all assignments done to it will cast the right-hand-side to its class.

另一方面,uint64(13286492335502040542)调用"将由MATLAB解释器进行优化,以避免为double参数调用uint64函数的开销,并将文字直接转换为其无符号整数表示形式(准确).

On another hand, the uint64(13286492335502040542) "call" will be optimized by the MATLAB interpreter to avoid the overhead of calling the uint64 function for the double argument, and will convert the literal directly to its unsigned integer representation (which is exact).

另一方面,函数调用优化不适用于

On a third hand [sic], the function call optimization doesn't apply to

p = uint64([13286492335502040542;13286492335502040543])

因为uint64的参数不是文字,而是表达式的结果,即应用于两个double操作数的vertcat运算符的结果.在这种情况下,MATLAB解释器不够聪明,无法弄清楚两个函数调用应该通勤"(uint的串联应与串联的uint相同),因此它会评估串联(给出等于,因为FP精度),然后将两个相似的double值转换为uint64.

because the argument of uint64 is not a literal, but the result of an expression, i.e. the result of the vertcat operator applied to two double operands. In this case the MATLAB interpreter is not smart enough to figure out that the two function calls should "commute" (concatenation of uint should be the same as uint of concatenation), so it evaluates the concatenation (which gives an array of equal double because FP precision), then converts the two similar double values to uint64.

TLDR:之间的区别

p = uint64(13286492335502040542);

u = 13286492335502040542; p = uint64(u);

是函数调用优化的副作用.

is a side effect of function call optimization.

这篇关于uint64对于Matlab中的向量不完全正确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆