How to display exactly 2^64?

I want to display 2^64 exactly as 18446744073709551615, without e. Without using vpa(), how can I display18446744073709551615?
Any help is appreciated!
Thanks a lot!

1 Comment

"2^64 exactly as 18446744073709551615"
2^64 is actually 18446744073709551616, not 18446744073709551615.

Sign in to comment.

 Accepted Answer

Ameer Hamza
Ameer Hamza on 7 Oct 2020
Edited: Ameer Hamza on 7 Oct 2020
First, 2^64 is not exactly 18446744073709551615. It is 18446744073709551616. 2 to any power cannot be an odd number.
Second, this number is beyond flintmax so the number near it, e.g., 2^64-1 cannot be exactly represented using double-precision floating-point. Even for uint64, the maximum value is 2^64-1. The other option is to use a variable precision library, i.e., vpa() or symbolic arithmetic.
If you don't want to use the symbolic toolbox, then download this big decimal library from here: https://www.mathworks.com/matlabcentral/fileexchange/36534-hpf-a-big-decimal-class. It works perfectly for variable precision mathematics.
x = hpf(2);
y = x^64
Result
y =
18446744073709551616
Some inaccurate statements were fixed as pointed out in Stephen's comment: https://www.mathworks.com/matlabcentral/answers/606841-how-to-display-exactly-2-64#comment_1041516

7 Comments

Okay, Thanks a lot!
If I want to display 2^64-1 precisely, what should I do?
If you use hpf, then there you can simply write
x = hpf(2);
y = x^64-1
If you insist on not using any external library, then 2^64-1 can also be displayed using the following line
y = uint64(inf) % it is maximum number for uint64
Result
>> y
y =
uint64
18446744073709551615
Thanks! what if I want to display only the number 18446744073709551615, without 'unit64'? still not using any external library
Following will work in this case
disp(uint64(inf))
Result
>> disp(uint64(inf))
18446744073709551615
"Second, this number is beyond flintmax, so it cannot be accurately represented by double datatype."
Actually, it can be.
Being above flintmax does not mean that no integer values can be exactly represented, it means that not all integer values can be represented. Integer powers of two can definitely be exactly represented (and some other too... just not all integers. In fact every floating point number above flintmax is an integer).
"No native data type in MATLAB is capable of accurately representing 2^64."
Both single and double exactly represent all integer powers of two within realmin and realmax.
Lets take a closer look:
>> num2hex(pow2(64)) % double
ans =
43f0000000000000
>> num2hex(pow2(single(64))) % single
ans =
5f800000
Or in equivalent binary form (sign exponent fraction):
Double:
0 10000111111 0000000000000000000000000000000000000000000000000000
Single:
0 10111111 00000000000000000000000
In both cases the fraction value is exactly 1 (the implicit leading digit is 1). For the single the exponent is
>> bin2dec('10111111')
ans =
191
which taking into account the offset of 127 gives a value of:
1*2^(191-127)
1*2^64
So that single exactly represents the value of 2^64. Ditto for the double.
Thank you very much! This is exactly what I want!
Better, if you wanted to create arbitrarily high precision INTEGERS, is to use VPI. HPF is fine, except that you will need to define how many digits to use, whereas VPI has no explicit limit on the number of digitis except those induced by the available memory. HPF essentially uses a fixed number of decimal digits, although that number will be set by the user.
But since the request is to not need any external library to represent the number, both VPI and HPF fail that goal. One other option is to use java.
java.math.BigInteger.pow(java.math.BigInteger(2),64)
ans = 18446744073709551616
Or even seriously higher powers can be computed now.
java.math.BigInteger.pow(java.math.BigInteger(2),1024)
ans = 179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137216
In fact 2^1024 is just a small number in terms of the abilities of the java.math.BigInteger tools. I've used that tool to work with numbers with hundreds of thousands of digits, and that barely scratches the surface in terms of capability. For example, while I won't display it, 2^1e8 takes only a tiny fraction of a second to compute, and that is a pretty big integer.
tic,x=java.math.BigInteger.pow(java.math.BigInteger(2),100000000);toc
Elapsed time is 0.002492 seconds.
And Java is sort of already included with MATLAB. Except that it will one day go away, something we know lies in the future. But for now, the BigInteger solution is perfectly valid.

Sign in to comment.

More Answers (3)

val = 2^64 ;
fprintf("%f\n",val)

6 Comments

Thank you! But I don't want to display a decimal point and digits after the decimal point, what should I do then?
val = 2^64 ;
fprintf("%.f\n",val)
And I find that the answer is 18446744073709551616.000000,,where the last unit is different from what I want.
Thank you very much! You help solve the problem.
Does not display the correct value on R2012b:
>> fprintf('%f\n',2^64)
18446744073709552000.000000
>> fprintf('%.f\n',2^64)
18446744073709552000
Or R2015b:
>> fprintf('%f\n',2^64)
18446744073709552000.000000
>> fprintf('%.f\n',2^64)
18446744073709552000
Same question with Walter regexp "why 53 bit precision won't play a role?"
And why this give wrong answer
>> val = 2^64 - 1;
>> fprintf("%.f\n",val-1)
18446744073709551616

Sign in to comment.

Bruno Luong
Bruno Luong on 7 Oct 2020
Edited: Bruno Luong on 7 Oct 2020
They teach me this when I was kid
% Raise to power 2^64
d=1;
for p=1:64
r=0;
for i=length(d):-1:1
a=2*d(i)+r;
r=floor(a/10);
d(i)=a-r*10;
end
if r>0
d = [r d];
end
end
% substract b (==1 here) to d=2^64
s = [1];
sp = [zeros(1,length(d)-length(s)) s];
r=0;
for i=length(d):-1:1
a=d(i)+r-sp(i);
r=floor(a/10);
d(i)=a-r*10;
end
if r<0
error('overflow (b>d)');
end
d = char(d+'0');
fprintf('%s\n', d)
regexprep(sprintf('%.19lu\n', 2^64), {'\.', 'e.*$'}, {'', ''})
ans = '18446744073709551616'

5 Comments

Bruno Luong
Bruno Luong on 7 Oct 2020
Edited: Bruno Luong on 7 Oct 2020
Hmmm, why 53 bit precision won't play a role?
Edited according to Stephen comment below
Luong, double-precision, is able to represent all powers of 2 accurately. Even 2^1023 is correctly represented. What it cannot do is 2^64-1, or any other integer beyond flintmax except powers of 2.
>> y1 = sym(2)^1023;
>> y2 = sym(2^1023);
>> isequal(y1, y2)
ans =
logical
1
But following fails
>> y1 = sym(2)^1023-1;
>> y2 = sym(2^1023-1);
>> isequal(y1, y2)
ans =
logical
0
Stephen23
Stephen23 on 7 Oct 2020
Edited: Stephen23 on 7 Oct 2020
"double-precision, is able to represent all powers of 2 accurately. Even 2^1023 is correctly represented. What it cannot do is 2^64-1, or any other integer beyond flintmax."
???
Powers of two (like 2^1023 or 2^64) are integers beyond flintmax. The statement "What it cannot do is... any other integer beyond flintmax" contradicts the first/second sentences.
Thanks for pointing out, the statement was ambiguous. I have updated the comment.
Bruno Luong
Bruno Luong on 7 Oct 2020
Edited: Bruno Luong on 7 Oct 2020
Still not accurate: 3*2^1000 is exactly represented by double/single, it's not power of two either.

Sign in to comment.

Asked:

on 7 Oct 2020

Edited:

on 12 Oct 2020

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!