Pages:
Author

Topic: 21million BTC is just over 51 bits of precision... - page 2. (Read 4582 times)

donator
Activity: 826
Merit: 1039
...there is no reason to use floating-point rather than a simple int64...
JSON-RPC doesn't support an Integer type. So it's floating-point or string.
legendary
Activity: 2576
Merit: 1186
The integer 2100000000000001 is within the range that is represented EXACTLY in double-precision floating point. On the other hand, the number 2100000.000000001 is not (and cannot be) represented exactly in double precision floating point (because it has a decimal fraction part that cannot be exactly represented in the binary encoding used for floating point).

The limit for exact integer representation in a double precision floating point number is 9,007,199,254,740,992 which is sufficient for Bitcoin's needs.
But so long as we are working in base units, there is no reason to use floating-point rather than a simple int64...
donator
Activity: 826
Merit: 1039
Bitcoin could send a number that looks like 2100000000000001, but the code that interprets that JSON-RPC number will convert it into an inexact double-precision floating-point equivalent.  And then the code that displays that number will have to decide how to round and format that inexact floating point number and display it to the user.

Gavin, my point is this:

The integer 2100000000000001 is within the range that is represented EXACTLY in double-precision floating point. On the other hand, the number 2100000.000000001 is not (and cannot be) represented exactly in double precision floating point (because it has a decimal fraction part that cannot be exactly represented in the binary encoding used for floating point).

The limit for exact integer representation in a double precision floating point number is 9,007,199,254,740,992 which is sufficient for Bitcoin's needs.

Perhaps you understood that I was saying that, and are pointing out that we are at the mercy of JSON libraries that might not correctly handle the conversion from integer to double-precision.

If the libraries are that buggy, it's pretty sad.
legendary
Activity: 2576
Merit: 1186
JSON-RPC numbers ARE ALWAYS double-precision floating point numbers (according to the JavaScript/ECMAScript spec).
JSON is not defined by the ECMAScript standard. The actual JSON standard does not define any precision, or even that numbers are floating-point.
legendary
Activity: 1652
Merit: 2216
Chief Scientist
ribuck:

Accuracy/precision is a red-herring unless you're treating numbers as strings, since JSON-RPC numbers ARE ALWAYS double-precision floating point numbers (according to the JavaScript/ECMAScript spec).  Bitcoin could send a number that looks like 2100000000000001, but the code that interprets that JSON-RPC number will convert it into an inexact double-precision floating-point equivalent.  And then the code that displays that number will have to decide how to round and format that inexact floating point number and display it to the user.

When we need more than 51 bits of precision (wouldn't THAT be a fantastic problem to have!), then we'd HAVE to send numbers as strings, and have the JavaScript (or whatever) on the other end feed them into a bignum-type library to handle them.
legendary
Activity: 2576
Merit: 1186
But ... what about when the whole world is using bitcoin and the precision gets extended beyond 51 bits?
As I understand it, precision cannot be extended without rewriting the whole system and starting from a new genesis (which might be a copy of the old "final block" I suppose). In any case, 51 bits of precision does seem to be enough, even for the whole world: Tonal BitCoin is based on 1,0000 (65,536 decimal) base units, which yields a maximum of 7,750,54.00 (32 billion decimal) TBC-- enough for 4 TBC per human, if every human (unlikely the entire world adopts BitCoin anyway) had the same number (which is itself unlikely too). From there, there are still 16 bits of precision left for division into 1,0000 (65,536 decimal) TBCᵇ pieces. Worst case, each of these TBCᵇ should still be small enough for any significant spending, and smaller divisions could be done with a separate micro-transaction network trading 1000:1 with these.
legendary
Activity: 1526
Merit: 1129
I really don't think BitCoins should ever be represented as floats except for presentation to humans.

At some point it's quite possible that we'll want to move the decimal place around. If anything it'd be good to start thinking about how to organize that. Having the point hard-coded into APIs would cause issues.
donator
Activity: 826
Merit: 1039
Murphy's Law states that some JSON libs are broken. Use integers, don't use floating point.
If you have enough bits of floating point precision, you can represent integers safely and exactly. But you can't do the same for decimal fractions, due to the binary representation within the floating point value.

So if you represent the bitcoins as bitdust (2,100,000,000,000,000) rather than as coins (21,000,000.00000000) it should work unless the library is extremely broken (in which case it's likely to be extremely broken for integers too).

But ... what about when the whole world is using bitcoin and the precision gets extended beyond 51 bits?
mrb
legendary
Activity: 1512
Merit: 1027
gavinandresen: Murphy's Law states that some JSON libs are broken. Use integers, don't use floating point.

Smiley
administrator
Activity: 5222
Merit: 13027
I've observed float-type errors (0.9999999, etc.) from bitcoind output (when using bitcoind as the RPC client), though this was in a very old release. Does Bitcoin still do this? (I patched my version to use strings for all numbers.)
legendary
Activity: 1652
Merit: 2216
Chief Scientist
luke-jr's patches got me thinking about whether or not passing double-precision values over the JSON-RPC api would ever cause problems.  I've convinced myself it isn't an issue:

JSON numbers are 64-bit double-precision floating point values, which have 53 bits of precision.

21 million bitcoins is actually 2,100,000,000,000,000 (2.1 quadrillion) of the smallest possible unit.  That's a bit over 251 -- you need just over 51 bits to represent them.

So, unless your JSON library is buggy, you should never run into rounding errors converting to/from JSON, even if you're sending 0.00000001 bitcoins.
Pages:
Jump to: