What is the max number of digits allowed for a base 2 number?
Show older comments
I am working with base 10 integers in the quadrillion range. My understanding is that when converted to base 2, such numbers end up being about 50 digits. What is the max number of digits MATLAB allows for base 2 numbers?
Answers (1)
Fangjun Jiang
on 4 Feb 2025
Edited: Fangjun Jiang
on 4 Feb 2025
The default data type in MATLAB is "double", which means 64 bits. When used to represent a base 2 number, its maximum value is 2^64-1 (the value of intmax('uint64')), which is significantly larger than a quadrillion (10^15).
For 64 bits or under, you can use bin2dec() directly.
quadrillion =10^15
a=uint64(2^64-1)
double(a)
intmax('uint64')
dec2bin(a)
dec2bin(quadrillion)
dec2hex(a)
dec2hex(quadrillion)
bin2dec(repmat('1',[1,64]))
bin2dec(repmat('1',[1,65]))
9 Comments
Walter Roberson
on 4 Feb 2025
bin2dec() returns a double precision value. Double precision has 53 significant bits, so values greater than 2^53 might not be represented properly.
Converting values with 50 significant bits should be fine.
This answer is misleading. IEEE 64-bit double precision only has 52-bits in the significand, 53-bits if you include the hidden leading bit. It simply can't represent all the binary bits for anything larger. Your example is simply spitting out the max uint64 value. E.g.
format longg
2^64
num2hex(2^64)
num2hex(2^64-1)
num2hex(2^64-1000)
Why are these the same? Because the 1 and 1000 are both well below the eps(2^64) value:
eps(2^64)
So you end up with the same result because the inputs are actually exactly the same:
sprintf('%20.0f',2^64)
And this number actually overflows the max uint64 value, so what you get in the conversions below is simple range clipping at the upper value:
uint64(2^64)
uint64(2^64-1)
uint64(2^64-1000)
You need to stay under flintmax if you want to work with binary number conversions with doubles and maintain all the significant bits.
flintmax
log2(flintmax)
You are right. Using 2^64-1 or 2^64-2 is incorrect because it uses "double" size floating point data. However, the point holds true that MATLAB readily supports 64 bits of integer data.
dec2bin(intmax('uint64'))
dec2bin(intmax('uint64')-1)
dec2bin(intmax('uint64')-2)
If you want to use arithmetic to create the uint64 value 2^64-2 carefully you could do:
two = uint64(2);
x = two*(two^63-1) % Avoid computing 2^64 directly
y = intmax('uint64')-1 % (2^64-1)-1
This is the same type of approach I use when creating large symbolic values without going through double precision first.
T = sym(2);
q = T^2000-1 % greater than realmax
lastDigit = mod(q, 10) % last digit is in fact odd as expected
I = 2^2000-1 % Overflows to infinity in double precision
S = sym(2^2000-1) % Too late, already Inf before sym gets called
Walter Roberson
on 4 Feb 2025
dec2bin() is able to handle uint64.
Unfortunately though, bin2dec() can only reliably handle up to flintmax.
John D'Errico
on 5 Feb 2025
Edited: John D'Errico
on 5 Feb 2025
This is incorrect:
"The default data type in MATLAB is "double", which means 64 bits. When used to represent a base 2 number, its maximum value is 2^64-1 "
Yes, a double does use 64 bits, or 8 bytes. And, a double is the default daya type. But that is where your correct-ness ends.
A DOUBLE in MATLAB does NOT store 64 bits in the way you state. It stores 52 bits of precision, combined with a sign bit, and the remaining 11 bits to store an exponent.
As such, the largest number a double can store exactly is flintmax = 2^53-1, thus the largest integer you can store with 52 binary bits. That is the largest base 2 number a double can store exactly. If you exceed that point, then a double fails to provide exact storage.
X = flintmax('double')
num2str(X,55)
But now see that if we try to increment X by 1, a double has a problem.
X + 1 == X
Yes, a UINT64 number can store 64 bits as an unsigned integer. But UINT64 is a very different thing from a double, and it is NOT the default data type in MATLAB.
Fangjun Jiang
on 5 Feb 2025
Moved: Fangjun Jiang
on 5 Feb 2025
Yes. I should not have mentioned the "double" data type. I shall say that MATLAB has the int64 and uint64 data type for the OP's need.
intmax('uint64')
a=intmax('uint64')-1
dec2bin(a)
class(uint64(10)-1)
Do note that as many of us have said, if you're working with numbers near intmax('uint64') you need to be a bit careful with how you create them. Simply defining them numerically and calling uint64 on the result won't necessarily work.
x = uint64(2^64-(1:4))
By the time MATLAB "sees" the uint64 call it's already performed the calculation in double precision. How far apart are numbers on the order of 2^64 spaced?
eps(2^64)
This differs from
x = uint64(2^64)-uint64(1:4)
The 2^64 gets evaluated in double precision. Then uint64() gets applied and saturates the 2^64 to (2^64-1). Then the subtraction takes place.
Compare
x = uint64(18446744073709551615) - uint64(0:3)
In this case, uint64(LITERALCONSTANT) is parsed as a uint64 value without loss of precision -- but that parsing only applies to literal constants, not to expressions (even if the expressions are effectively constant)
Categories
Find more on Logical in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!