text: # Decimal Fixed Precision
  
  ## 02 July 2019 - 1 answer
  
  I would like to use decimal in currency calculations, so I would like to work on exactly two numbers after comma. Initially I thought that `prec` of decimal's context refers to that property, but after a few experiments I feel a bit confused.
  
  Experiment #1:
  
  ``````In [1]: import decimal
  
  In [2]: decimal.getcontext().prec = 2
  
  In [3]: a = decimal.Decimal('159.9')
  
  In [4]: a
  Out[4]: Decimal('159.9')
  
  In [5]: b = decimal.Decimal('200')
  
  In [6]: b
  Out[6]: Decimal('200')
  
  In [7]: b - a
  Out[7]: Decimal('40')
  ``````
  
  Experiment #2:
  
  ``````In [8]: decimal.getcontext().prec = 4
  
  In [9]: a = decimal.Decimal('159.9')
  
  In [10]: a
  Out[10]: Decimal('159.9')
  
  In [11]: b = decimal.Decimal('200')
  
  In [12]: b
  Out[12]: Decimal('200')
  
  In [13]: b - a
  Out[13]: Decimal('40.1')
  ``````
  
  Experiment #3: (`prec` is still set to 4)
  
  ``````In [14]: a = decimal.Decimal('159999.9')
  
  In [15]: a
  Out[15]: Decimal('159999.9')
  
  In [16]: b = decimal.Decimal('200000')
  
  In [17]: b
  Out[17]: Decimal('200000')
  
  In [18]: b - a
  Out[18]: Decimal('4.000E+4')
  ``````
  
  Why does it work like in my examples? How should I work with decimals in my (currency calculations) case?
  
  The precision sets the number of significant digits, which is not equivalent to the number of digits after the decimal point.
  
  So if you have a precision of 2, you'll have two significant digits, so a number with 3 significant digits like `40.1` will be reduced to the upper two significant digits giving `40`.
  
  There's no easy way to set the number of digits after the decimal point with `Decimal`. However you could use a high precision and always `round` your results to two decimals:
  
  ``````>>> from decimal import Decimal, getcontext
  >>> getcontext().prec = 60  # use a higher/lower one if needed
  >>> Decimal('200') - Decimal('159.9')
  Decimal('40.1')
  >>> r = Decimal('200') - Decimal('159.9')
  >>> round(r, 2)
  Decimal('40.10')
  ``````
  
  The decimal FAQ also includes a similar question and answer (using `quantize`):
  
  Q. In a fixed-point application with two decimal places, some inputs have many places and need to be rounded. Others are not supposed to have excess digits and need to be validated. What methods should be used?
  
  A. The quantize() method rounds to a fixed number of decimal places. If the Inexact trap is set, it is also useful for validation:
  
  ``````>>> TWOPLACES = Decimal(10) ** -2       # same as Decimal('0.01')
  >>> # Round to two places
  >>> Decimal('3.214').quantize(TWOPLACES)
  Decimal('3.21')
  >>> # Validate that a number does not exceed two places
  >>> Decimal('3.21').quantize(TWOPLACES, context=Context(traps=[Inexact]))
  Decimal('3.21')
  >>> Decimal('3.214').quantize(TWOPLACES, context=Context(traps=[Inexact]))
  Traceback (most recent call last):
  ...
  Inexact: None
  ``````
  
  Q. Once I have valid two place inputs, how do I maintain that invariant throughout an application?
  
  A. Some operations like addition, subtraction, and multiplication by an integer will automatically preserve fixed point. Others operations, like division and non-integer multiplication, will change the number of decimal places and need to be followed-up with a quantize() step:
  
  ``````>>> a = Decimal('102.72')           # Initial fixed-point values
  >>> b = Decimal('3.17')
  >>> a + b                           # Addition preserves fixed-point
  Decimal('105.89')
  >>> a - b
  Decimal('99.55')
  >>> a * 42                          # So does integer multiplication
  Decimal('4314.24')
  >>> (a * b).quantize(TWOPLACES)     # Must quantize non-integer multiplication
  Decimal('325.62')
  >>> (b / a).quantize(TWOPLACES)     # And quantize division
  Decimal('0.03')
  ``````
  
  In developing fixed-point applications, it is convenient to define functions to handle the quantize() step:
  
  ``````>>> def mul(x, y, fp=TWOPLACES):
  ...     return (x * y).quantize(fp)
  >>> def div(x, y, fp=TWOPLACES):
  ...     return (x / y).quantize(fp)
  
  >>> mul(a, b)                       # Automatically preserve fixed-point
  Decimal('325.62')
  >>> div(b, a)
  Decimal('0.03')
  ``````
explanation: The document is a technical discussion about using the `decimal` module in Python for currency calculations, specifically focusing on how to set and maintain a fixed number of decimal places. The text starts with a series of experiments demonstrating the behavior of the `decimal` module with different precision settings. It then includes a question about why the experiments behave as they do and how to properly handle currency calculations. The document also provides an answer, explaining that the precision setting controls the number of significant digits, not the number of decimal places. It suggests using the `quantize` method to maintain a fixed number of decimal places and provides examples of how to do this.
distilabel_metadata.content: Evaluate the user given text extract and determine if it contains a math question and optionally and answer to this question.
  
  Output rules:
  
  1. Briefly describe the document and mention if it contains a question or a question and answer.
  2. Finalize the output with: Label: no-question,question,question-and-answer,multiple-question,multiple-question-and-answer
distilabel_metadata.role: system
distilabel_metadata.content: # Decimal Fixed Precision
  
  ## 02 July 2019 - 1 answer
  
  I would like to use decimal in currency calculations, so I would like to work on exactly two numbers after comma. Initially I thought that `prec` of decimal's context refers to that property, but after a few experiments I feel a bit confused.
  
  Experiment #1:
  
  ``````In [1]: import decimal
  
  In [2]: decimal.getcontext().prec = 2
  
  In [3]: a = decimal.Decimal('159.9')
  
  In [4]: a
  Out[4]: Decimal('159.9')
  
  In [5]: b = decimal.Decimal('200')
  
  In [6]: b
  Out[6]: Decimal('200')
  
  In [7]: b - a
  Out[7]: Decimal('40')
  ``````
  
  Experiment #2:
  
  ``````In [8]: decimal.getcontext().prec = 4
  
  In [9]: a = decimal.Decimal('159.9')
  
  In [10]: a
  Out[10]: Decimal('159.9')
  
  In [11]: b = decimal.Decimal('200')
  
  In [12]: b
  Out[12]: Decimal('200')
  
  In [13]: b - a
  Out[13]: Decimal('40.1')
  ``````
  
  Experiment #3: (`prec` is still set to 4)
  
  ``````In [14]: a = decimal.Decimal('159999.9')
  
  In [15]: a
  Out[15]: Decimal('159999.9')
  
  In [16]: b = decimal.Decimal('200000')
  
  In [17]: b
  Out[17]: Decimal('200000')
  
  In [18]: b - a
  Out[18]: Decimal('4.000E+4')
  ``````
  
  Why does it work like in my examples? How should I work with decimals in my (currency calculations) case?
  
  The precision sets the number of significant digits, which is not equivalent to the number of digits after the decimal point.
  
  So if you have a precision of 2, you'll have two significant digits, so a number with 3 significant digits like `40.1` will be reduced to the upper two significant digits giving `40`.
  
  There's no easy way to set the number of digits after the decimal point with `Decimal`. However you could use a high precision and always `round` your results to two decimals:
  
  ``````>>> from decimal import Decimal, getcontext
  >>> getcontext().prec = 60  # use a higher/lower one if needed
  >>> Decimal('200') - Decimal('159.9')
  Decimal('40.1')
  >>> r = Decimal('200') - Decimal('159.9')
  >>> round(r, 2)
  Decimal('40.10')
  ``````
  
  The decimal FAQ also includes a similar question and answer (using `quantize`):
  
  Q. In a fixed-point application with two decimal places, some inputs have many places and need to be rounded. Others are not supposed to have excess digits and need to be validated. What methods should be used?
  
  A. The quantize() method rounds to a fixed number of decimal places. If the Inexact trap is set, it is also useful for validation:
  
  ``````>>> TWOPLACES = Decimal(10) ** -2       # same as Decimal('0.01')
  >>> # Round to two places
  >>> Decimal('3.214').quantize(TWOPLACES)
  Decimal('3.21')
  >>> # Validate that a number does not exceed two places
  >>> Decimal('3.21').quantize(TWOPLACES, context=Context(traps=[Inexact]))
  Decimal('3.21')
  >>> Decimal('3.214').quantize(TWOPLACES, context=Context(traps=[Inexact]))
  Traceback (most recent call last):
  ...
  Inexact: None
  ``````
  
  Q. Once I have valid two place inputs, how do I maintain that invariant throughout an application?
  
  A. Some operations like addition, subtraction, and multiplication by an integer will automatically preserve fixed point. Others operations, like division and non-integer multiplication, will change the number of decimal places and need to be followed-up with a quantize() step:
  
  ``````>>> a = Decimal('102.72')           # Initial fixed-point values
  >>> b = Decimal('3.17')
  >>> a + b                           # Addition preserves fixed-point
  Decimal('105.89')
  >>> a - b
  Decimal('99.55')
  >>> a * 42                          # So does integer multiplication
  Decimal('4314.24')
  >>> (a * b).quantize(TWOPLACES)     # Must quantize non-integer multiplication
  Decimal('325.62')
  >>> (b / a).quantize(TWOPLACES)     # And quantize division
  Decimal('0.03')
  ``````
  
  In developing fixed-point applications, it is convenient to define functions to handle the quantize() step:
  
  ``````>>> def mul(x, y, fp=TWOPLACES):
  ...     return (x * y).quantize(fp)
  >>> def div(x, y, fp=TWOPLACES):
  ...     return (x / y).quantize(fp)
  
  >>> mul(a, b)                       # Automatically preserve fixed-point
  Decimal('325.62')
  >>> div(b, a)
  Decimal('0.03')
  ``````
distilabel_metadata.role: user
distilabel_metadata.raw_output_q_a_detector_0: The document is a technical discussion about using the `decimal` module in Python for currency calculations, specifically focusing on how to set and maintain a fixed number of decimal places. The text starts with a series of experiments demonstrating the behavior of the `decimal` module with different precision settings. It then includes a question about why the experiments behave as they do and how to properly handle currency calculations. The document also provides an answer, explaining that the precision setting controls the number of significant digits, not the number of decimal places. It suggests using the `quantize` method to maintain a fixed number of decimal places and provides examples of how to do this.
  
  Label: question-and-answer