## Expand description

A format for exchanging arbitrary precision decimal floating-point numbers.

This library converts text-based numbers like `-123.456e7`

into bitstrings like `01010110_10001110_10010010_10100010`

.

Specifically, it implements support for an **IEEE 754 compatible
decimal floating-point bitstring, using
densely-packed-decimal encoding, in
little-endian byte-order**. Along with the bitstring encoding there is an
equivalent text-based one that can represent all the same values. High-level types that convert between these two formats
and standard Rust numeric types are provided.

## Encoding

The following table demonstrates how various numbers are encoded as 32bit decimals by this library to give you an idea of how the format works:

text | binary |
---|---|

bit layout | `tttttttt_tttttttt_ggggtttt_sggggggg` |

0 | `00000000_00000000_01010000_00100010` |

-0 | `00000000_00000000_01010000_10100010` |

0e1 | `00000000_00000000_01100000_00100010` |

123 | `10100011_00000000_01010000_00100010` |

-123 | `10100011_00000000_01010000_10100010` |

123.456 | `01010110_10001110_00100010_00100010` |

-123.456 | `01010110_10001110_00100010_10100010` |

inf | `00000000_00000000_00000000_01111000` |

-inf | `00000000_00000000_00000000_11111000` |

nan | `00000000_00000000_00000000_01111100` |

snan | `00000000_00000000_00000000_01111110` |

-nan | `00000000_00000000_00000000_11111100` |

-snan | `00000000_00000000_00000000_11111110` |

nan(123) | `10100011_00000000_00000000_01111100` |

snan(123) | `10100011_00000000_00000000_01111110` |

where:

`s`

: The sign bit.`g`

: The combination field.`t`

: The trailing significand.

Note that this library *always* encodes in little-endian byte-order, regardless of the endianness of the underlying platform.
Also note, this encoding is different on big-endian platforms than `libdecimal`

’s internal encoding, which isn’t specified, but
currently uses arrays of 32bit integers.

More sizes besides 32bit are supported. The table uses it to minimize space.

## Why decimal bitstrings?

The decimal bitstrings specified in IEEE 754 aren’t as widely known as their binary counterparts, but are a good target for exchanging numbers.

Compared with text, decimal bitstrings are:

- Compact. Instead of encoding 1 digit per byte (8 bits), you get 3 digits per 10 bits.
- Cheap to classify. You can tell from a single byte whether or not a number is positive, negative, whole, infinity, or NaN. You don’t need to reparse the number.

Compared with binary (base-2) bitstrings, decimal bitstrings are:

- Easy to convert between text. You don’t need arbitrary-precision arithmetic to encode a human-readable number into a decimal bitstring.
- Precise. You can exactly encode base-10 numbers, which is the base most modern number systems use.
- Consistent. They’re a newer standard, so they avoid some ambiguities around NaN payloads and signaling that affect the portability of binary bitstrings.

## Features and limitations

This library *only* does conversions between Rust’s primitive number types, numbers encoded as text, and decimal bitstrings.
It’s not an implementation of decimal arithmetic. It also doesn’t do rounding. If a number can’t be encoded in a decimal
bitstring of a given width then you’ll get `None`

s instead of infinities or rounded values.

Decimal numbers in IEEE 754 are non-normalized by-design. The number `1.00`

will encode differently to `1`

or `1.0`

.

This library does support very high precision in no-std, and can work with arbitrary precision when the
`arbitrary-precision`

feature is enabled.

## Conversions

### Binary floating point

This library can convert binary floating points (`f32`

and `f64`

) into decimals.
It uses ryū to pick an appropriate decimal representation and faithfully encodes that.
The following cases are worth calling out:

`0f64`

will encode as`0.0`

, which is different to`0`

.- A signaling NaN is encoded as a quiet NaN.
- NaN payloads are discarded.

### Exponents

The exponent range of a decimal depends on its width in bits. Wider decimals support a wider exponent range. The actual exponent you can write in a decimal also depends on whether the number is fractional. For example, the following all encode the same number at the edge of decimal64’s exponent range:

`100e369`

`10.0e370`

`1.00e371`

## Structs

- An arbitrary precision decimal number.
- A dynamically sized decimal number with enough precision to fit any Rust primitive number.
- An error encountered converting between decimals and primitive types.
- An error encountered while working with decimals.
- An error encountered creating a buffer to encode a decimal into.
- An error encountered parsing a decimal from text.