Pages:
Author

Topic: Stop using floating point! - page 2. (Read 28414 times)

newbie
Activity: 10
Merit: 1
June 09, 2011, 01:38:27 AM
#5
Quote
Double precision IEEE numbers have more than enough precision to represent any possible bitcoin amount.

As long as you represent things as integer nanocoins, and do only addition and subtraction, none of the things mentioned are going to have any effect.

If you're representing "things" as integer nanocoins, then why don't you use an integer type?!

An uint64 would work just fine!!

UINT64_MAX = 18446744073709551615
BITCOIN_MAX = 21000000 * 10^ 8 = 2100000000000000

BITCOIN_MAX < INT64_MAX

So you want to do that just because you like to get yourself into trouble?

Do you know what optimizations the compiler is allowed to do in intermediate values of floating point calculations?

Do you know that certain compilation flags affect the precision of the results (downwards or upwards)?

Do you know that when you enable some optimizations in some compilers, they don't follow the standards?
Such as when you use -fast with the Sun Studio compiler or -ffast-math in gcc?

Do you know that many Linux Gentoo users use -ffast-math by default?

Also, I didn't see any place in the code where "integer nanocoins" are represented as floating point values (granted, I only read a fraction of the code). What I saw was integer nanocoins being used as integers, and floating point bitcoins being used in floating point variables...

Please, just use integer (i.e. fixed point) arithmetic for financial data and stop writing shoddy code. It's a no brainer, really...
full member
Activity: 327
Merit: 124
June 09, 2011, 01:09:43 AM
#4
Please learn to use fixed-point arithmetic, people... this is not a pet project anymore, it's a financial application that at the moment holds $181 million USD worth of people's savings.

I think you might need a lesson on how floating point works.
In short, results of rounding, calculations and comparisons may vary depending on compiler, optimizations, or architecture used.
Furthermore, there are other non-obvious semantics, such as negative zeros, infinities, NaNs, etc.

Double precision IEEE numbers have more than enough precision to represent any possible bitcoin amount.

As long as you represent things as integer nanocoins, and do only addition and subtraction, none of the things mentioned are going to have any effect.

BASIC used double precision floats for everything for decades, and it worked just fine for integer calculations, within a reasonable range.

If you multiply and divide, and want things like banker's rounding, then floating point can be a bit problematical, but for tallying transactions, it works fine.

 
newbie
Activity: 10
Merit: 1
June 09, 2011, 01:03:44 AM
#3
Good point.
Where did you find this piece of code? In the client?

Yes, v0.3.22.
newbie
Activity: 47
Merit: 0
June 09, 2011, 12:54:21 AM
#2
Good point.
Where did you find this piece of code? In the client?
newbie
Activity: 10
Merit: 1
June 08, 2011, 10:15:45 PM
#1
Can we stop with this nonsense?

+    if (params[0].get_real() != 0.0)
+        nAmount = AmountFromValue(params[0]);        // rejects 0.0 amounts


          if (strMethod == "sendtoaddress"          && n > 1) ConvertTo(params[1]);
+        if (strMethod == "settxfee"               && n > 0) ConvertTo(params[0]);


Please learn to use fixed-point arithmetic, people... this is not a pet project anymore, it's a financial application that at the moment holds $181 million USD worth of people's savings.

I think you might need a lesson on how floating point works.
In short, results of rounding, calculations and comparisons may vary depending on compiler, optimizations, or architecture used.
Furthermore, there are other non-obvious semantics, such as negative zeros, infinities, NaNs, etc.

I know in this case the comparison with 0.0 is probably not problematic, but for instance, you don't want someone to send a transaction of 0.12345678 bitcoins and then due to rounding conversions you actually send 0.12345679 bitcoins instead. Or someone to set a transaction fee of 0.2 and instead it gets set to 0.19999999.

It is NOT acceptable for financial applications to use floating point numbers to represent monetary values.
Governments have strict regulations against this for banks, for obvious reasons.

Please, please avoid using floating point arithmetic and educate yourselves why you should do that.

For example, there's a reason why Satoshi avoided floating point calculations in many places (e.g. difficulty calculations... you really don't want different machines having a different concept of what the difficulty is).

What you really want is to convert strings directly to fixed-point numbers (probably with BigDecimals if uint64 is not enough for 21,000,000*10^8 individual units) and vice-versa.
Always do calculations, comparisons and range checks with fixed-point arithmetic.

http://objectopia.com/2009/07/03/stop-using-floating-poin/
http://programmers.stackexchange.com/questions/62948/what-can-be-done-to-programming-languages-to-avoid-floating-point-pitfalls
http://www.theregister.co.uk/2006/08/12/floating_point_approximation/
http://hal.archives-ouvertes.fr/docs/00/28/14/29/PDF/floating-point-article.pdf

... and so on and on...

Same advice goes for the code of any website that deals with bitcoins (MtGox and mining pools come to mind...).
Pages:
Jump to: