Author

Topic: Why you can't use "0.1" in bitcoin code safely (Read 755 times)

sr. member
Activity: 439
Merit: 250
mmmmmm
August 05, 2014, 11:12:41 PM
#4
We're not doing any math with the block reward code, other than the initial * COIN, so one might argue, the issue of block halving would become an issue far sooner than the block reward, since there could be feasibly some precision loss and desynchronization accross different platforms once the formula moves from * COIN to /2 * COIN;

there are probably safeguards in place to prevent this anyway, probably thought of by the original creator of bitcoin. Also, remember bitcoin units are only required to be precise to 8 decimal places, leaving a rather large margin of error.

No, you're misunderstanding how the code actually works. In the code, there is no nothing but satoshis. "1" in the native unit of bitcoin, is a satoshi. COIN is defined as 10*8. All units in bitcoin are stored and conveyed using a 64bit integer, not a floating point number. There is a reason for this, and there is a reason that no protocol critical code uses floating point numbers. Programmers have heard of things like 0.1+0.1 = 0.19999999901 and such related horrors, well imagine that for the block reward, but it's also not consistent. So, the wallet on your raspberry pi thinks that the block reward should be 0.1999172. and the wallet on your x86 PC, thinks it should be 0.199999999998. and the wallet on your Android device using ARM thinks it should be 0.19998.
hero member
Activity: 686
Merit: 504
always the student, never the master.
We're not doing any math with the block reward code, other than the initial * COIN, so one might argue, the issue of block halving would become an issue far sooner than the block reward, since there could be feasibly some precision loss and desynchronization accross different platforms once the formula moves from * COIN to /2 * COIN;

there are probably safeguards in place to prevent this anyway, probably thought of by the original creator of bitcoin. Also, remember bitcoin units are only required to be precise to 8 decimal places, leaving a rather large margin of error.
sr. member
Activity: 294
Merit: 250
Bitmark Developer
Why not create a small unit test application and host it on github, something which tests that the values expected are produced.

Link us to it, and post it in the technical section, many people will run it, if or when it fails we can then take some action.
sr. member
Activity: 439
Merit: 250
mmmmmm
I just wanted to give a quick FYI to all the coin devs and future coin devs.

When you use "0.2*COIN" to represent 0.2 coins, it is not safe. Floating point values in C++ are not guaranteed to be exact, and they are not guaranteed to be consistent across platforms or even compilers. Please stop doing this. For more information, see this stackoverflow question.

The proper way to represent a division of coins is to either represent it as satoshis (ie, without COIN), or to use only integers, such as "2*COIN/10" to represent 0.2 coins.

This WILL cause forks and bad wallets on non-x86 architectures, such as the raspberry pi and many others and is in general a very bad practice.
Jump to: