0

I'm new to Python and I am having problems with floating point arithmetic. From what I understand, floating point arithmetic in Python generates binary approximations of decimal values and we deal with floating point values either by using the round() function, string formatting methods or the decimal.Decimal class.

However all of these require constantlly writing round(), decimal.Decimal() or string formatting methods during calculations. Is there a way to modify the preexisting float class in a particular program so that all calculations as well as storage of float values take place after rounding to a certain number of decimal places? Alternatively, can we create a new class to do this?

I have tried the second method and my code is:

    class Float(float):
            def count_decimal_places(float_num):
                    if type(float_num) == int:
                            return 0
                    return len(str(float_num).split('.')[1])
            def __add__(self, other):
                    return round(self +other, max(count_decimal_places(self), count_decimal_places(other)))

This should return 3 + -1.6 as 1.4 and not 1.399999999998. However the above code doesn't work either.

Anmol Saksena
  • 91
  • 2
  • 10
  • Does this answer your question? [Is floating point math broken?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) – quamrana Nov 09 '20 at 15:07
  • No, I understand the underlying logic for why this occurs. I am looking for a way to overcome the problem by slightly modifying the existing float datatype or creating a custom one – Anmol Saksena Nov 09 '20 at 15:16
  • What do you expect the result of `1.0 / 3.0` to be? What about the result of `(1.0 / 3.0) * 3.0`? – Sneftel Nov 09 '20 at 15:51
  • I haven't defined the overloaded multiplication method in the custom Float class I pasted the code for, but the function should return a 3 decimal place rounded result on multiplication/division so whenever multiplication/division operations are performed on these values, the results are saved after automatically rounding. – Anmol Saksena Nov 09 '20 at 16:05
  • Honestly, if you're constantly rounding then you're doing it wrong. Ask yourself whether the binary floating-point imprecision for values that can be represented exactly in decimal really matters for what you're doing. (Ex: If you're doing scientific calculations, it very likely doesn't. If you're doing accounting, it may well matter.) If it matters, use `Decimal` throughout: that's what it's for. If not, use `float` and live with the 1-part-in-a-thousand-million-million order-of-magnitude errors in calculations, and use string formatting for pretty output where necessary. – Mark Dickinson Nov 09 '20 at 16:20
  • @AnuragSaksena So you're saying that `(1.0 / 3.0) * 3.0` should return 0.999 instead of 1? – Sneftel Nov 10 '20 at 09:26

0 Answers0