为什么 sprintf('%i', x) 显示科学记数法?



在Matlab R2015b:中尝试此操作

>> sprintf('%in',uint64(2)^62)
ans =
4611686018427387904 %// correct
>> sprintf('%in',uint64(2)^63)
ans =
9.223372e+18 %// why scientific notation?

在R2010b中,情况更糟:低至uint64(2)^31的数字已经导致了这种行为:

>> sprintf('%in',uint64(2)^31)
ans =
2.147484e+009

为什么sprintf使用带有'%i''%d'格式说明符的科学记数法?这能避免吗

使用num2str而不是sprintf对我来说不是一个解决方案。尽管它确实避免了科学记数法,

>> num2str(uint64(2)^63)
ans =
9223372036854775808 %// correct

我需要使用sprintf,因为num2str不支持"前导空格"格式说明符:

>> sprintf('% 25in',uint64(2)^62, uint64(2)^50)
ans =
      4611686018427387904
         1125899906842624 %// correct: leading spaces to give 25 characters for each number
>> num2str([uint64(2)^62;uint64(2)^50], '% 25in')
ans =
4611686018427387904
   1125899906842624 %// incorrect: no leading spaces
>> num2str(uint64(2)^50, '% 25in')
ans =
1125899906842624 %// incorrect: no leading spaces

看看这个问题,MATLAB似乎出于某种原因(可能是因为它期望从%i得到一个有符号整数,但你给它的是一个无符号整数),将非常大的数字(2^63)视为float,并将其转换为科学符号,这也是为什么如果你写sprintf('%.18in',bitshift(uint64(2),62)),你最终会失去精度:

9.223372036854775800e+18 vs. 9223372036854775808

使用%u而不是%i似乎产生了正确的结果:

sprintf('%un',bitshift(uint64(2),62))
ans =
9223372036854775808

(在这种特定场景中使用bitshift更有意义)

最新更新