Pages:
Author

Topic: Developers - Best practises for decimal handling - page 2. (Read 3217 times)

legendary
Activity: 1890
Merit: 1086
Ian Knowles - CIYAM Lead Developer
Using Integers:
  • Ensure that all calculations do not accept any decimal value and rounding is performed at integer level
  • Ensure you have strict controls in your UI layer to process raw figures into the correct decimal representations
  • * the tricky aspect here is knowing whether a figure read is a currency figure or a btc figure

Using float/decimals:
  • Ensure that all calculations are subject to the correct decimal rounding (eg if BTC, then always round every calculation to 8dp.
  • Ensure that every language used represents decimals correctly

Although I would still very much recommend using integers over binary FP if you do the rounding at all the right points (and this is harder with FP if you are going to be doing multiple calculations) then you should of course end up with the same result.
donator
Activity: 848
Merit: 1078
I've worked in my real jobs extensively in retail and investment banking on a range of trading and reporting systems. Not a single one I have come across represents monetary value in integer format. (hence this discussion thread) Rounding within all banking systems (in my experience at least) occurs programatically in functions.

That's interesting - certainly all the banking software that I've seen (am talking *bank end* not UI) is still written in COBOL (developed in the 70's and patched in the 90's for the Y2K bug) where you use PIC variables which let you describe the numeric as a number of digits and number of decimal places.

Am pretty certain that *under the covers* these are actually represented as integers (just not seen that way by the programmer even) as they don't suffer from the "binary floating point problems".


My experience has mostly been with back end systems so raw data in SQL databases and mainframes. Data inputs for their front end systems will only accept 2 decimal places as valid data. Anything else input from either a data feed or directly would be rejected as a bad data input.

I don't believe that it would matter whether you represent values in integer or in floating point as long as you have programmed your controls correctly. For calculations and rounding, there should can be a few issues. Eg:

Using Integers:
  • Ensure that all calculations do not accept any decimal value and rounding is performed at integer level
  • Ensure you have strict controls in your UI layer to process raw figures into the correct decimal representations
  • * the tricky aspect here is knowing whether a figure read is a currency figure or a btc figure

Using float/decimals:
  • Ensure that all calculations are subject to the correct decimal rounding (eg if BTC, then always round every calculation to 8dp.
  • Ensure that every language used represents decimals correctly
member
Activity: 116
Merit: 11
Storing as integers is the most common way I think. Depending on your framework/database it can differ however. For example in Django you could use DecimalField.
legendary
Activity: 1890
Merit: 1086
Ian Knowles - CIYAM Lead Developer
I've worked in my real jobs extensively in retail and investment banking on a range of trading and reporting systems. Not a single one I have come across represents monetary value in integer format. (hence this discussion thread) Rounding within all banking systems (in my experience at least) occurs programatically in functions.

That's interesting - certainly all the banking software that I've seen (am talking *bank end* not UI) is still written in COBOL (developed in the 70's and patched in the 90's for the Y2K bug) where you use PIC variables which let you describe the numeric as a number of digits and number of decimal places.

Am pretty certain that *under the covers* these are actually represented as integers (just not seen that way by the programmer even) as they don't suffer from the "binary floating point problems".
donator
Activity: 848
Merit: 1078
One should always calculate and store in integer base units when dealing with Bitcoin amounts. Pool operators and other sites that have previously stored values in floats have been shamed out of existence.

There is consensus that from all the replies so far that integers are the way forward, and I would totally agree, from a IT/developer's perspective this makes sense.

I've worked in my real jobs extensively in retail and investment banking on a range of trading and reporting systems. Not a single one I have come across represents monetary value in integer format. (hence this discussion thread) Rounding within all banking systems (in my experience at least) occurs programatically in functions.

however work will be required in the display logic of a site / program.
I don't see how this is a problem. You're already using extra logic to escape user input, format timestamps, generate urlencoded links, etc.

Agreed, it isn't an issue however the logic would either have to be built into the calculation layer (ie your programming) or the visual presentation layer if you were to store values in decimal or integer format respectively. I'd like to know what everybody's preference is and why.

Second to this, looking at the mtgox api, values are stored in not one, not two, but THREE formats:
  • Display value
  • Float/Double/Decimal value
  • Integer value
legendary
Activity: 980
Merit: 1003
I'm not just any shaman, I'm a Sha256man
If you use my library (Bitcoin Dev Kit) forces you to use integers for math/proccessing while displaying is in your choice dynamically between decimal and integers. Aswell as other helpfull features like make bitcoind communication smoother and wont block your website and make it render blank on a minor bitcoin error (like low balance,etc).
legendary
Activity: 1890
Merit: 1086
Ian Knowles - CIYAM Lead Developer
There are multiple ways to *round* and any decent *numeric* implementation will let you choose the one that suits you best.

If you use a 64 bit integer type and create a *numeric* class around that then you will have no problems with the range of values required for Bitcoin (and pretty much all currencies). As has already been pointed out *binary* floating point types are *not* suitable for financial software.

Welcome to take a look at the numeric class that CIYAM uses: https://github.com/ciyam/ciyam/blob/master/src/numeric.cpp
full member
Activity: 154
Merit: 100
One point that hasn't been mentioned that I've seen be a problem is rounding. I've seen posts on the forum where some site has said they have X amount, but it turns out that really they have ever so slightly less than that amount and it's been rounded up, so when they try to send, they get an error saying 'not enough funds!' which is very confusing. So the moral of this story is to round *down* if you aren't going to display the whole balance down to 8 decimal places.
sr. member
Activity: 293
Merit: 250
however work will be required in the display logic of a site / program.

I don't see how this is a problem. You're already using extra logic to escape user input, format timestamps, generate urlencoded links, etc.

Storing satoshi values in integer format is the sensible thing to do. Just like storing unix timestamps instead of the date string.

You should never store BTC values as floats. You cannot guarantee that your favorite language / web framework / database will handle them the way you expect them to be handled.
legendary
Activity: 1512
Merit: 1036
One should always calculate and store in integer base units when dealing with Bitcoin amounts. Pool operators and other sites that have previously stored values in floats have been shamed out of existence.

The only time it would be even close to acceptable would be if you are dividing or multiplying by a non-integer and want to maintain an even higher degree of accuracy internally in accounts (such as my $0.00000 in mtgox), and then you must ensure that your platform and any other that may run your code will store in IEEE 754 double floats or greater.

Another way bitcoin was more thought out than you may understand: There will be a maximum of 0x775F05A074000 bitcoin base units ever in existence, which is a 51 bit number. From wikipedia "'double precision' (64-bit) binary floating-point number has a coefficient of 53 bits (one of which is implied), an exponent of 11 bits, and one sign bit.".

donator
Activity: 848
Merit: 1078
I'd like to open up a discussion about the different way you as developers have approached the problems of decimal handling when working on bitcoin projects.

Because bitcoin is divisible down to 8 decimal places, calculations on float / decimal numbers can be a pain in a number of languages (as numbers may never appear exact even if displayed correctly).

When working on the MtGox api, they have marked the decimal value representations as legacy. It appears they are moving away from anything decimal related and using integers (which is multiplied by 1e-8 when displayed for bitcoin). This makes calculations simpler in whatever language you are programming in, however work will be required in the display logic of a site / program.

What are your programming practises for handling the many decimals that bitcoin provides?

I'd like to hear from you if you run a bitcoin site or even a wallet program, btcjam / satoshidice / electrum etc... ?
Pages:
Jump to: