【问题标题】:Why does sprintf('%i', x) show scientific notation?为什么 sprintf('%i', x) 显示科学计数法?
【发布时间】:2015-11-06 22:30:24
【问题描述】:

在 Matlab R2015b 中试试这个:

>> sprintf('%i\n',uint64(2)^62)
ans =
4611686018427387904 %// correct

>> sprintf('%i\n',uint64(2)^63)
ans =
9.223372e+18 %// why scientific notation?

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

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

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

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

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

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

>> sprintf('% 25i\n',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], '% 25i\n')
ans =
4611686018427387904
   1125899906842624 %// incorrect: no leading spaces

>> num2str(uint64(2)^50, '% 25i\n')
ans =
1125899906842624 %// incorrect: no leading spaces

【问题讨论】:

  • 这是因为超出了最大整数大小(2^63-1 afaik)吗?
  • @Adriaan 不,这不可能是原因,因为最大值实际上是2^64-1
  • 恕我直言,这听起来像是一个错误。
  • @rayryeng 另请参阅num2str(rand(1,3) * 9999, '% 25.5e\n') 的结果:空格左填充,除了第一个。也很奇怪
  • 您是否尝试过%u 用于无符号整数?

标签: string matlab printf


【解决方案1】:

看着this question,似乎 MATLAB 出于某种原因(可能是因为它期望来自 %i 的有符号整数,但您给它的是一个无符号整数),它处理了非常大的数字 (2^ 63)作为float,并将其转换为科学记数法,这也是为什么如果你写sprintf('%.18i\n',bitshift(uint64(2),62))你最终会失去精度:

9.223372036854775800e+18 vs. 9223372036854775808

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

sprintf('%u\n',bitshift(uint64(2),62))

ans =

9223372036854775808

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

【讨论】:

  • 不仅仅是很大——特别是临界值是intmax('int64') (2^63-1)。始终使用适当的格式说明符。
猜你喜欢
  • 1970-01-01
  • 2011-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-16
  • 1970-01-01
  • 2013-05-27
相关资源
最近更新 更多