1

Hello I am working with a lot of numbers like this: 0.00000005, 0.000341, 3423.52322154. Basically bitcoin and altcoin numbers.

Now I know that if I do this for example in python

>>> 0.1 + 0.2
0.30000000000000004

It's not correct and that I can str my variables and put them inside Decimal module to fix it. My problem is that I don't know when float is /good enough/ and because I am probably a bit autistic when it comes to performance and understanding what I'm doing I am thinking that I'm perhaps using decimal module too much when it isn't needed.

So how can I know when I need to use Decimal when I'm doing math and when I don't have to?

Edit: Ok, a lot of people are assuming that because im dealing with bitcoin and altcoin numbers i want to calculate it to buy exact sums or whatever, that is not the case always for me. I also want to take like 200 numbers every second and quickly calculate amount * rate for displayment purposes and perhaps float can be good enough. I suppose there's no easy answer for these things though(i suppose i have to read up on binary representation of numbers etc).

Also people have suggested i represent the numbers as integers and then also store the decimal place and then put it back after the calculation. I don't know if this is faster than decimal?

n00p
  • 269
  • 4
  • 11
  • 2
    If you're dealing with money, `float`s not good enough – Nick is tired Jan 19 '18 at 16:46
  • You might need a whole book to answer. See http://floating-point-gui.de/ ; BTW your question is unclear or too broad, and off-topic (since without any [MCVE]) – Basile Starynkevitch Jan 19 '18 at 16:46
  • 3
    When you don't need the result to be completely accurate. Ex: Calculating the position of a character in a video game at x,y. Does it really matter if x,y is off by .0001? No. Are you doing accounting? Working with money? You don't use float. If you are concerned about your calculations being off by .0000000000004 in the first place then just use the correct type and don't use float. Don't make a workaround to pass them to another function if there is a remainder. – Jacob H Jan 19 '18 at 16:47
  • I don't know anything about these virtual coins, but any currency operation shouldn't be done with floating point arithmetic (unless it's a hobby project and you don't care to an extent about being 100% accurate) – DPM Jan 19 '18 at 16:47
  • Does it matter to you that `0.1 + 0.2 == 0.30000000000000004`? If so, don't use float. – glibdud Jan 19 '18 at 16:50
  • 1
    Possible duplicate of [Clarification on the Decimal type in Python](https://stackoverflow.com/questions/20354423/clarification-on-the-decimal-type-in-python) – Nick is tired Jan 19 '18 at 16:50
  • 1
    In a nutshell: anything *visual* (charts, screen coordinates, 3D renderings) usually doesn't need to be terribly precise and can get away with fast floats. Anything outside of that you need to know for yourself whether your numbers need to be *accurate* or *fast*. Chances are if you're just doing *light arithmetic* and are not crunching millions of numbers per second, you prefer *accuracy*. – deceze Jan 19 '18 at 16:51
  • 3
    "When can I safely use float to do math?" -- when you don't care about the resulting round-off error. – John Coleman Jan 19 '18 at 17:12

2 Answers2

2

Python has the decimal module that comes along with he language: although it is technically "floating point", it really deals with decimal numbers up to the precision of digits you specify.

So it is possible to use the 18 or so numbers after the decimal point some of the cryptocurrencies use (like ethereum) with zero erros introduced due to base shift or rounding.

>>> from decimal import Decimal as D
>>> D("0.1") + D("0.2") 
Decimal('0.3')
>>> (D("0.1") + D("0.2")) * D("0.00000000001") + D("0.1") 
Decimal('0.100000000003')
>>> 

It may look artificial since Decimal instances have to be constructed from strings, but that is just to avoid the errors like those you see in first place. These objects support all numeric operations, and can be easily be converted to strings with no rounding errors for usage on any API you have.

https://docs.python.org/3/library/decimal.html

jsbueno
  • 99,910
  • 10
  • 151
  • 209
0

If it needs to be very precise, you shouldn't really use floats. Instead you should store two integers, one that has the number without a decimal point and one that shows how many decimal places it should divide into while displaying or something.

The times that float may be useful is when you are doing operations that are within 3 or 4 decimal places, you can use the round function to the amount of desired decimal places after every calculation.

Hippolippo
  • 803
  • 1
  • 5
  • 28