Reputation: 1498
I'm trying to print the value:
(2^32 - 1) * (2^32 - 1)
in MATLAB and have it display all 20 digits. I've tried
fomat long
and
sprintf('%20d',ans)
Neither of these are getting the results I want and print:
1.844674406511962e+19
or something to that effect. Any advice?
Upvotes: 2
Views: 433
Reputation: 30589
You are right to expect %d
to print an integer as an integer, requiring no precision or field width specification, rather than in exponential notation (%e
). There is a reason why sprintf
fails to display this integer as an integer. Here's why (and more).
From the sprintf
documentation, this is the output format that %d
specifies:
Integer, signed;
%d
or%i
; Base 10
The keyword here is signed. This does specify an integer printed in decimal (base 10) notation, but the sign takes up one bit! The largest integer you (and %d
) can represent with a 64-bit signed integer (i.e. int64
) is 2^63-1
(check with intmax('int64')
). And since (2^32 - 1) * (2^32 - 1) > 2^63-1
, sprintf
falls back to exponential notation (%e
). But don't take my word for it:
>> sprintf('%d',uint64(2^63)-1)
ans =
9223372036854775807
>> sprintf('%d',uint64(2^63))
ans =
9.223372e+18
The solution is to use the unsigned integer format: %u
.
>> sprintf('%u',uint64(2^63))
ans =
9223372036854775808
With (2^32 - 1) * (2^32 - 1)
, the issue is less subtle, but the solution is the same:
>> val = (2^32 - 1) * (2^32 - 1); % > 2^63-1
>> sprintf('%u',val)
ans =
18446744065119617024
This answers the question, but this is still wrong. This time it's not sprintf
's fault. Double precision (64-bit) floating point numbers can only represent integers up to 2^53 without loss of precision1. Since the default data type in MATLAB is double
, val
is stored as a double
. To ensure no loss of precision, use the uint64
type:
>> valUI = uint64(2^32 - 1) * uint64(2^32 - 1)
>> sprintf('%u',valUI)
ans =
18446744065119617025
Close. double
almost got lucky.
1This value of 2^53 (or 9,007,199,254,740,992) can be verified by flintmax('double')
.
Upvotes: 3
Reputation: 3786
To turn the scientific notation off, try this:
format long g
Upvotes: 0
Reputation: 36720
You must increase the precision, which is the number following the .
in the format spec:
sprintf('%.20d',ans)
Upvotes: 1