On 25 January 2014 08:57, spir <denis.s...@gmail.com> wrote: > On 01/25/2014 09:46 AM, spir wrote: >> >> On 01/24/2014 06:57 PM, Leon S wrote: >>> >>> Here is what I'm trying to do, accept a price of gas, but I want to add >>> the >>> .009 to the price, so that people do not have to type the full amount. >>> Example, 3.49 /gallon would return 3.499 /gallon. >>> >>> This is what I have tried and the results of it. >>> >>> def gas_price(price): >>> price == raw_input("What is the price of gas?") return price + .09 >>> 3.49=> 3.4899999999999998 >>> >>> It reduces the number and then adds many decimal points after. >>> >>> Thanks for any help, I am sure this is an easy one for someone. >> >> This is instead easy for noone ;-) >> >> The core issue is that for, say, "fractional numbers" (numbers with a >> fractional >> part, but unlike real numbers with definite precision) python like most >> programming languages uses in standard a binary representation internally. >> While >> we normally use decimal notation, both in input (reading) and output >> (writing). >> And there is no way to represent decimal fractions in binary, except in >> the very >> case where they are a multiple of an exact (negative) power of 2 (for >> instance >> 1/2, 3/4, 123/128... are ok). >> >> The only right solution is to use decimals internally, and python provides >> such >> a numeric type, Decimal: >> http://docs.python.org/3/library/decimal.html > > I did not read correctly. If you're dealing with financial as it seems, the > right way is to use integers instead.
I would say that using Decimal is the "right" solution for financial calculations. Using integers (AKA fixed-point arithmetic) is possible and is the standard solution for languages that lack a Decimal type. > Since you are adding tenth's of pence, > this is what your unit means. Then your sum is: > 3490 + 9 > :-) > > Note: AFAIK most financial software use integers for this reason and to > avoid (or control) rounding errors. The Decimal module allows you to avoid or control rounding errors. If it is true that most financial software uses fixed-point arithmetic instead of floating point decimal arithmetic then I would guess that the most likely reason is that the language used for the software doesn't have a library for floating point decimal arithmetic as Python does. A significant motivating use-case for adding the Decimal module and for subsequently speeding it up with a C implementation was to support using Python in the context of financial software. > At input and/or output, you may still have to convert to Decimal to get > "decimally correct" value or expression. > > numeral = input("...") > value = Decimal(numeral) > ... > output = Decimal(result) / Decimal("1000") > print(output) > > (not sure, not tried) I would do it like so: >>> from decimal import Decimal >>> def adjust_price(price): ... return Decimal(price) + Decimal('.005') ... >>> adjust_price('3.49') Decimal('3.495') >>> print(adjust_price('3.49')) 3.495 But then what happens if the use has added the .005 themselves: >>> print(adjust_price('3.495')) 3.500 Perhaps we should round down before adding .005: >>> from decimal import ROUND_DOWN >>> def adjust_price(price): ... # Round down to 2 decimal places ... price = Decimal(price).quantize(Decimal('1.00'), rounding=ROUND_DOWN) ... return price + Decimal('.005') ... >>> print(adjust_price('3.49')) 3.495 >>> print(adjust_price('3.495')) 3.495 Of course now you'll get: >>> print(adjust_price('3.497')) 3.495 Maybe that's not what was wanted either (I'm not sure exactly what you do want in this case). Oscar _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor