Pages:
Author

Topic: Stop using floating point! (Read 28398 times)

legendary
Activity: 2128
Merit: 1073
February 17, 2012, 01:44:10 PM
#25
This thread is very sad. Bitcoin is seriously affected with not-invented-here-itis. I personally started to think that the current milieu here is hopeless. The only hope is that the currently involved software designers fall of the face of the Earth's Internet and get replaced by a new blood.

On the other hand I also know that a lot of bright young people read this forum. So for the benefit of the young blood:

1) please learn the difference between binary floating point and decimal floating point. The good starting point is: http://speleotrove.com/decimal/

2) please compile this little C program using your recent C compiler:
Code:
#include 
int main()
{
        _Decimal32 x,y;

        x = 1.df;
        x /= 10.df;
        y = x;
        y *= 10.df;
        printf("%Hf %Hf\n",x,y);
        return 0;
}
For example: "gcc d.c -ldfp". If you get "library not found for -ldfp" error, then read the following and complain to your software vendor.

3) You became a collateral damage in the mortal combat between IBM and Intel. They are both pushing two incompatible implementations of decimal floating point: IBM's DPD (densely packed decimal) and Intel's BID (binary integer decimal). The libdfp code is out there on the Internet, you'll need to search for it in places that aren't easily accessible to lawyers of the two concerns that I named above.
hero member
Activity: 868
Merit: 1008
February 16, 2012, 11:50:48 PM
#24
This debate is silly.  If you're really a purist, forget scaled decimal and use integers and fractions.  Smalltalk was invented in the 70's and by default, it preserves the original representation of numbers...  "1 / 2" yields a fraction with the integer 1 as the numerator and 2 as the denominator.  Multitply it by 3 and you get another fraction, "3 / 2".  Multiply that by 2 and you get the integer "3" (yes, it reduces fractions).  You don't get better precision than that.  A 64bit floating point number has plenty of precision to deal with anything bitcoin needs…try "21000000.00000002 / 2" …it works.  When working with floating point within its bounds of precision, you only need to know enough about math to know when it's appropriate to round.
legendary
Activity: 1232
Merit: 1076
legendary
Activity: 2058
Merit: 1452
February 12, 2012, 10:28:59 PM
#22
From what i can tell, bitcoinhelper (lol @ "helper") is just randomly quoting pieces of code and ranting about how we shouldn't use floats for everything. but for some reason, he didn't realize that floats are only used in GUI related stuff.

something tells me that he is either a kid who gets really hyped up about small issues (looks like he made an account just to post this topic Roll Eyes), or a troll.

and he's a necro  Angry
sr. member
Activity: 270
Merit: 250
February 12, 2012, 10:07:33 PM
#21

Thanks I've been waiting over 7months to click that link.
legendary
Activity: 1652
Merit: 2301
Chief Scientist
June 09, 2011, 10:55:26 PM
#19
See https://en.bitcoin.it/wiki/Proper_Money_Handling_(JSON-RPC) for relevant advice.

As Pieter says, bitcoin converts all user-entered values and JSON-RPC values to fixed-point 64-bit integers as soon as it gets them. All calculations except for that conversion are done using 64-bit integers.

Bitcoin does not "use floating point", it parses numbers-containing-a-decimal-point values that come from JSON (the Number type in JSON is double-precision float; let's not restart the "we should pass numbers as strings in JSON" debate, please, there are several long threads from a couple of months ago about that) or from the GUI.
sr. member
Activity: 312
Merit: 250
June 09, 2011, 04:12:36 PM
#18
No one would ever use double to represent nanocoins.  This whole issue is probably because people think of 0.00000001BTC rather than 1Satoshi.  Don't use floats with indivisible units.

hero member
Activity: 994
Merit: 501
PredX - AI-Powered Prediction Market
June 09, 2011, 02:48:07 PM
#17
After seeing that, I almost felt the urge of selling all my BTC..

Seriously O.o floating point?

I am a game programmer (among other stuff programmer), and I had MANY bugs that were "theoretically to not happen" with floating point.

A infamous one for example, was in a game that I made using LUA, that 5998 + 3 resulted into 6010 (yes, way wrong).

After a while, I found out, that LUA use floating point to all internal math, and the game engine I used, triggered the stupid floating point bug of directx (directx sometimes change the settings of CPU and GPU floating point, making them non-complient with the floating point standard).

So, DO NOT ASSUME YOU CAN WORK WITH INTEGER VALUES USING FLOAT! IT WILL SOMEHOW BREAK WHEN YOU DO NOT EXPECT!
newbie
Activity: 10
Merit: 1
June 09, 2011, 02:45:35 PM
#16
In reality, floats represent exact values on the real number line, and the result of a floating operation is the nearest machine number to the value that would have resulted had the operation been performed to infinite precision if one exists, and a value systematically chosen with zero bias if the exact value lies halfway between two machine numbers.

And BTW, in most financial calculations you don't want to perform operations to infinite precision.

What you want is to have predictable results that do not depend on the environment used to compile and/or run the application.
hero member
Activity: 630
Merit: 500
June 09, 2011, 02:40:43 PM
#15
My view is that a steady migration to fixed integers is needed. We don't need to rush, but it needs to happen. What's going on right now is perfectly correct, but it's not ideal from a semantic view and feels like a kludge.
newbie
Activity: 10
Merit: 1
June 09, 2011, 02:25:57 PM
#14
I have no problem with requiring new code to be fixed point.

Great!

  I am simply pointing out that removing existing floating point code isn't an emergency, that floating point arithmetic is exact when integers having less bits than the mantissa are involved, that panic over imagined precision or rounding issues when using floats for financial software is overblown, and that several Very High Level Languages popular for financial and actuarial work use floats internally, as does COBOL when performance is maximized.

It's exact for additions and subtractions (of values that were never divided).

If you divide one value by another, and now you add the result multiple times, you will likely obtain different results than if you had used fixed-point arithmetic (unless it was an exact division).

This can lead to results that are unexpected. It may also lead to different results depending on how the compiler optimized your code (e.g. whether it used SSE2 or the FPU), the architecture you're using, etc.

People seem to have the idea that all float operations involve some sort of random fuzziness which causes monetary calculations to drift from their actual values the more floating operations are performed.  In reality, floats represent exact values on the real number line, and the result of a floating operation is the nearest machine number to the value that would have resulted had the operation been performed to infinite precision if one exists, and a value systematically chosen with zero bias if the exact value lies halfway between two machine numbers.

It's not as obvious and simple as you seem to imply, as I just proved to you.

The code is also non-portable because the 'double' type in C++ is not required to have 64 bits, in fact it can have only 32 bits which is obviously not enough to represent all bitcoin values (not even close).
The size of double does not only depend on the architecture and compiler that you are using, but also on the compilation flags.
The double type is only required to not be smaller than float.
full member
Activity: 327
Merit: 124
June 09, 2011, 12:51:50 PM
#13
If it's true though, why bother using floats at all? 

I have no problem with requiring new code to be fixed point.  I am simply pointing out that removing existing floating point code isn't an emergency, that floating point arithmetic is exact when integers having less bits than the mantissa are involved, that panic over imagined precision or rounding issues when using floats for financial software is overblown, and that several Very High Level Languages popular for financial and actuarial work use floats internally, as does COBOL when performance is maximized.

People seem to have the idea that all float operations involve some sort of random fuzziness which causes monetary calculations to drift from their actual values the more floating operations are performed.  In reality, floats represent exact values on the real number line, and the result of a floating operation is the nearest machine number to the value that would have resulted had the operation been performed to infinite precision if one exists, and a value systematically chosen with zero bias if the exact value lies halfway between two machine numbers.

So floating operations which yield machine numbers are as exact as integer operations.  Since double floats are big enough to represent all Bitcoin amounts, discussion of whether or not to ban floating arithmetic in the source code of the default client is a philosophical one, and not one related to an actual danger the code will "break, or that Bitcoin amounts will become imprecise, if this is not done.

Comments like "such and such a company burns coders at the stake if they use floating point in financial apps," while interesting, make points orthogonal to the points I am making.

newbie
Activity: 88
Merit: 0
June 09, 2011, 10:06:06 AM
#12
Thank you for this thread, I have learned a lot because of it and will fix my projects accordingly.
legendary
Activity: 1072
Merit: 1181
June 09, 2011, 05:05:04 AM
#11
Internally, everything is represented using 64-bit integers. It's only some of the interfacing code that uses floating point for convenience. I agree this should change to as much exact code as possible, but as currently all supported platforms of the main client support 64-bit IEEE 754 floats, all roundings should be exact.
newbie
Activity: 54
Merit: 0
June 09, 2011, 04:53:58 AM
#10
Please, just use integer (i.e. fixed point) arithmetic for financial data and stop writing shoddy code. It's a no brainer, really...

Floating point arithmetic which can represent the integer values exactly isn't going to give a different answer than fixed point arithmetic.  Look at all the actuarial  programs written in APL, whose numeric prototype is a double precision float or complex.

The alleged horrors of float for financial math are mostly FUD.  Lots of COBOL programs use a comp-3 floating type because it is faster than character or packed decimal arithmetic. 
Statements like this make me wonder if you have ever written portable floating point code. 

You might be ok if the system you run on implements IEEE-754 rules.  However, this day & age the Bitcoin client is being run on more & more small devices, some of which might not even have an FPU.  Not only that, but those which do are very likely not to follow 754 rules in particular, making their output theoretically differ from the result on a 754-based machine.  Those bugs are so much fun to find.  Tongue

The bottom line is that quality programming starts with good discipline, and financial software should always use fixed point representations.  Some companies will literally fire you if they see floating point in your code, and it's not because they are stupid.
hero member
Activity: 504
Merit: 502
June 09, 2011, 04:39:20 AM
#9
Please, just use integer (i.e. fixed point) arithmetic for financial data and stop writing shoddy code. It's a no brainer, really...

Floating point arithmetic which can represent the integer values exactly isn't going to give a different answer than fixed point arithmetic.  Look at all the actuarial  programs written in APL, whose numeric prototype is a double precision float or complex.

So you're saying as long as we stick to representing integers with floats, there will be no problem with inaccuracy?  (You're quite right in this assertion).

If it's true though, why bother using floats at all?  They are only exact when not using fractional parts, so why not remove the danger and used fixed point integers and save ourselves the wasted bits of the exponent in the float representation?
sr. member
Activity: 286
Merit: 251
June 09, 2011, 03:49:57 AM
#8
I would like to chip in here and say I agree with bitcoinhelper.

Integers should be used for internal representation.

Integers have the property that they give the same result on every computer or an overflow occurs.
Floating point has the property that if the amount goes outside what can be represented on that particular computer approximation occurs.
Sometimes this is useful.

In this situation an error is way better than an approximation.

That is the point!
full member
Activity: 327
Merit: 124
June 09, 2011, 03:38:07 AM
#7
Please, just use integer (i.e. fixed point) arithmetic for financial data and stop writing shoddy code. It's a no brainer, really...

Floating point arithmetic which can represent the integer values exactly isn't going to give a different answer than fixed point arithmetic.  Look at all the actuarial  programs written in APL, whose numeric prototype is a double precision float or complex.

The alleged horrors of float for financial math are mostly FUD.  Lots of COBOL programs use a comp-3 floating type because it is faster than character or packed decimal arithmetic. 

As with all things, it helps if you know what you're doing, and one can always construct examples of failure that are poor programming practice or don't occur in real life.

On the list of things that need fixing in Bitcoin, floating compares to double 0.0 aren't anywhere near the top of the list.



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

Not to mention that the C++ standard allows the 'double' type to have only 4 bytes.... sigh  Undecided
Pages:
Jump to: