2015-11-06 85 views
1

在Matlab R2015b試試這個:爲什麼sprintf('%i',x)顯示科學記數法?

>> 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 
+1

這是因爲最大整數大小(2^63-1 afaik)是否超出? – Adriaan

+0

@Adriaan不,不可能是原因,因爲最大值實際上是[2^64-1](http://es.mathworks.com/help/matlab/ref/uint64.html) –

+0

聽起來像是錯誤恕我直言。 – rayryeng

回答

2

看着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更有意義)

+1

不僅非常大 - 特別是臨界值是'intmax('int64')'('2^63-1')。始終使用適當的格式說明符。 – horchler