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

Members

Classes

DivisionByZero
class DivisionByZero

Thrown when using Throw and division by zero occurs

InvalidOperation
class InvalidOperation

Thrown when using Throw and an invalid operation occurs

Overflow
class Overflow

Thrown when using Throw and overflow occurs

Underflow
class Underflow

Thrown when using Throw and underflow occurs

Enums

Rounding
enum Rounding

Controls what happens when the number of significant digits exceeds Hook.precision

Functions

abs
auto abs(D d)
decimal
auto decimal(R r)

Factory function

isInfinity
bool isInfinity(D d)
isNaN
bool isNaN(D d)

Structs

Abort
struct Abort

Will halt program on division by zero, invalid operations, overflows, and underflows.

Decimal
struct Decimal(Hook = Abort)

A exact decimal type, accurate to Hook.precision digits. Designed to be a drop in replacement for floating points.

HighPrecision
struct HighPrecision

Same as abort, but offers 64 significant digits

NoOp
struct NoOp

Does nothing on invalid operations except the proper flags

Throw
struct Throw

Will throw exceptions on division by zero, invalid operations, overflows, and underflows

Meta