Bug with large HEX numbers
37 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
Bug with large HEX numbers like 'fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141', which is final number for private keys for Bitcoin network.
This code
Final = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141
raises an error, which is a real bug!
1 Kommentar
Stephen23
am 18 Feb. 2025
Bearbeitet: Stephen23
am 18 Feb. 2025
"raises an error, which is a real bug!"
Not a bug.
The documentation on hexadecimal notation states that "By default, MATLAB stores the number as the smallest unsigned integer type that can accommodate it".
The integer types are listed here:
The largest representable integer value is
mxv = intmax('uint64')
which in hexadecimal is
sprintf('%lx',mxv)
and clearly a much much smaller number than fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141. So there is no possible way to store your large hexadecimal number using a standard numeric integer type, i.e. even if no error would be thrown then you would not get that value stored in memory.
You might be able to fit it into a double, but clearly only with loss of precision.
Antworten (1)
John D'Errico
am 18 Feb. 2025
Bearbeitet: John D'Errico
am 18 Feb. 2025
H = 'fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141';
numel(H)
So 64 hex digits, which would yield an integer on the order of
16^64
The standard data type use 8 bytes to store all numbers. This far exceeds the largest integer which can be stored in either a double or uint64.
Note, that when you do this in MATLAB, it automatically stuffs the result into an integer form, of the smallest size that it will fit.
Final = 0xab
Here, a uint8 will hold it. Add a few more digits, and it will use uint16, then iint32, then uint64. In each case, the result gets stuffed into an integer form.
Final = 0xab45
Final = 0xab45de2
Final = 0xab45de2df
However, if you go too far, as you pushed things, it generates the error you saw.
% Final = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141
That generates the error you saw, where you should recognize that MATLAB has no standard extended data type to store an arbitrarily large integer. To do that, you must work with it as a sym. (Or you could use some other big integer form, perhaps the Java.Math.BigInteger tools.)
Final = sym('0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141')
vpa(Final,100)
And of course, you can then convert back into hex form after you have done your work...
dec2hex(Final)
As such this this is NOT a bug in MATLAB! The only bug lies in your recognizance that you cannot stuff that large of an integer into the relatively small box provided by a UINT64.
2 Kommentare
Steven Lord
am 18 Feb. 2025
The standard data type use 8 bytes to store all numbers. This far exceeds the largest integer which can be stored in either a double or uint64.
John, I know you know what I'm about to write, but I wanted to call out for the original poster that there is some nuance to the second sentence. It is accurate that the number the poster wants to create is too large to store in a uint64, as it's greater than
M = intmax('uint64')
You can store numbers larger than this in MATLAB as double precision values, but one problem is that you can't store all integers on this order of magnitude in double.
x = 16^64
y = x+1
isequal(x, y) % true, and no this is NOT a bug!
Every finite number greater than flintmax is an integer value, but not all integer values greater than flintmax can be stored as a double. See x and y above. So there's no guarantee that MATLAB could store exactly that number in double precision. In order to get to the next representable integer after x, you'd have to add:
spacing = eps(x)
You can see this by looking at the hex representation of the double values x, y, and x+spacing. The last of those numbers differs from x by the last bit of the mantissa.
format hex
x
y
x+spacing
John and Stephen23 are correct: this is not a bug. You could file it with Technical Support as an enhancement request for MATLAB to add a larger integer type, like int128 and uint128.
John D'Errico
am 18 Feb. 2025
Lol. Good catch by @Steven Lord. It ends up being almost a philosophical issue. If I store a number in a double, and because the large number is a double, it does not store the number exactly, have I actually stored the number? That is, if I stuff a number of that magnitude into a double, it can and will store something (as long as the number is no larger than realmax), but only an approximation to what you supplied. From that point of view, it is as if I take a picture of you. Is the picture truly you? Or only a representation of you?
I'd argue that it only stores the actual number, IF after storing the number, you can then extract the original number in hex form to full precision.
Anyway, yes, a double will fit that number. But not exactly, and since what matters here are essentially ALL of the digits, then you cannot use a double or a UINT64 to do so.
Could you fit it into a UINT128? (If such a datatype was provided?) No. 64 hex digits would require a uint1024 datatype to store them all, since 64 hex digits corresponds to 1024 binary bits, thus 16*64. And that means you would need a UINT1024 datatype. You COULD send in a feature request for that to happen, but I'm not sure it will happen in the near future. Of course, that does not stop you from writing it yourself. Or, you could use my VPI toolbox, or SYMs, or the Java.Math.BigInteger tools. Any of those three tools are essentially unlimited in the number of bits they can store. Of course, they are much slower to work with, but you can have it fast, or you can have the correct result. Your choice.
Siehe auch
Kategorien
Mehr zu Numbers and Precision finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!