index

Modules

stdxdecimal
module stdxdecimal

* Quick_Start: * --- * import stdxdecimal; * * void main() * { * auto d1 = decimal("1.23E-10"); * d1 -= decimal("2.00E-10"); * assert(d1.toString() == "-0.000000000077"); * } * --- * * This module defines an exact decimal type, Decimal, to a specific number of digits. * This is designed to be a drop in replacement for built-in floating point numbers, * allowing all the same possible operations. * * Floating point numbers (float, double, real) are inherently inaccurate because * they cannot represent * all possible numbers with a decimal part. Decimal on the other hand, is able to * represent all possible numbers with a decimal part (limited by memory size and Hook). * * Adapted from the specification of the * General Decimal Arithmetic. * * Custom_Behavior: * The behavior of Decimal is controlled by the template parameter Hook, * which can be a user defined type or one of the Hooks provided by this * module. * * The following behaviors are controlled by Hook: * *

    *
  • The number of significant digits to store.
  • *

  • The rounding method.
  • *

  • The min and max exponents.
  • *

  • What to do when exceptional conditions arise.
  • *

* * The following predefined Hooks are available: * *

**

*

*

*

*

*

*

*

*

*

*

*

*

*

*

*

Abortprecision is set to 9, rounding is HalfUp, and the program * will assert(0) on divsion by zero, overflow, underflow, and * invalid operations. *
Throwprecision is set to 9, rounding is HalfUp, and the program * will throw an exception on divsion by zero, overflow, underflow, and * invalid operations. *
HighPrecisionprecision is set to 64, rounding is HalfUp, and the program * will assert(0) on divsion by zero, overflow, underflow, and * invalid operations. *
NoOpprecision is set to 9, rounding is HalfUp, and nothing will * happen on exceptional conditions. *

* * Percision_and_Rounding: * Decimal accurately stores as many as Hook.precision significant digits. * Once the number of digits > Hook.precision, then the number is rounded. * Rounding is performed according to the rules laid out in RoundingMode. * * By default, the precision is 9, and the rounding mode is RoundingMode.HalfUp. * * Hook.precision must be <= uint.max - 1 and > 1. * * Notes_On_Speed: * Increasing the number of possible significant digits can result in orders * of magnitude slower behavior, as described below. Only ask for as many digits * as you really need. * *

**

*

*

*

*

*

*

*

*

*

*

*

*

*

*

*

9 and below (default)Baseline
10-192x slower than baseline
20-100020x slower than baseline
1000 and above200x slower than baseline

* * Further, while it's possible to mix and match precisions in the various operations, * in this module, it results in a notable slow-down relative to the operation's * speed with two similar precisions. It's recommended that the user stick to one precision * throughout the program to avoid these issues. * * Exceptional_Conditions: * Certain operations will cause a Decimal to enter into an invalid state, * e.g. dividing by zero. When this happens, Decimal does two things * *

    *
  1. Sets a public bool variable to true.
  2. *

  3. Calls a specific function in Hook, if it exists, with the * operation's result as the only parameter.
  4. *

* * The following table lists all of the conditions * *

* $(THEAD * $(TR * $(TH Name) * $(TH Flag) * $(TH Method) * $(TH Description) * ) * ) * $(TBODY * $(TR * $(TD Clamped) * $(TD `clamped`) * $(TD `onClamped`) * $(TD Occurs when the exponent has been altered to fit in-between * `Hook.maxExponent` and `Hook.minExponent`. * ) * ) * $(TR * $(TD Inexact) * $(TD `inexact`) * $(TD `onInexact`) * $(TD Occurs when the result of an operation is not perfectly accurate. * Mostly occurs when rounding removed non-zero digits. * ) * ) * $(TR * $(TD Invalid Operation) * $(TD `invalidOperation`) * $(TD `onInvalidOperation`) * $(TD Flagged when an operation makes no sense, e.g. multiplying `0` * and `Infinity` or add -Infinity to Infinity. * ) * ) * $(TR * $(TD Division by Zero) * $(TD `divisionByZero`) * $(TD `onDivisionByZero`) * $(TD Specific invalid operation. Occurs whenever the dividend of a * division or modulo is equal to zero. * ) * ) * $(TR * $(TD Rounded) * $(TD `rounded`) * $(TD `onRounded`) * $(TD Occurs when the `Decimal`'s result had more than `Hook.precision` * significant digits and was reduced. * ) * ) * $(TR * $(TD Subnormal) * $(TD `subnormal`) * $(TD `onSubnormal`) * $(TD Flagged when the exponent is less than `Hook.maxExponent` but the * digits of the `Decimal` are not inexact. * ) * ) * $(TR * $(TD Overflow) * $(TD `overflow`) * $(TD `onOverflow`) * $(TD Not to be confused with integer overflow, this is flagged when * the exponent of the result of an operation would have been above * `Hook.maxExponent` and the result is inexact. Inexact and Rounded * are always set with this flag. * ) * ) * $(TR * $(TD Underflow) * $(TD `underflow`) * $(TD `onUnderflow`) * $(TD Not to be confused with integer underflow, this is flagged when * the exponent of the result of an operation would have been below * `Hook.minExponent`. Inexact, Rounded, and Subnormal are always set with * this flag. * ) * ) * ) *

* * Each function documentation lists the specific states that will led to one * of these flags. * * Differences_From_The_Specification: *

    *
  • There's no concept of a Signaling NaN in this module.
  • *

  • There's no concept of a Diagnostic NaN in this module.
  • *

  • compare, implemented as opCmp, does not propagate NaN due * to D's opCmp semantics.
  • *

* * Version: * v0.5. Still work in progress. For missing features, see README.md * * License: * Boost License 1.0. * * Authors: * Jack Stouffer