☰

# std/private/dragonbox

Theme:

- Manual
- Standard library
- Index
- Compiler docs
- Fusion docs
- devel, stable

Search:
Source Edit

Copyright 2020 Junekey Jeon Copyright 2020 Alexander Bolz

Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)

char* output_end = Dtoa(buffer, value);

Converts the given double-precision number into decimal form and stores the result in the given buffer.

The buffer must be large enough, i.e. >= DtoaMinBufferLength. The output format is similar to printf("%g"). The output is _not null-terminted.

The output is optimal, i.e. the output string

1. rounds back to the input number when read in (using round-to-nearest-even)
2. is as short as possible,
3. is as close to the input number as possible.

Note: This function may temporarily write up to DtoaMinBufferLength characters into the buffer.

This file contains an implementation of Junekey Jeon's Dragonbox algorithm.

It is a simplified version of the reference implementation found here: https://github.com/jk-jeon/dragonbox

The reference implementation also works with single-precision floating-point numbers and has options to configure the rounding mode.

namespace Returns floor(x / 2^n).

Technically, right-shift of negative integers is implementation defined... Should easily be optimized into SAR (or equivalent) instruction.

Returns whether value is divisible by 2^e2Returns whether value is divisible by 5^e5Returns (x * y) / 2^128

# Imports

digitsutils, assertions

# Types

    BitsType = uint64

  Source Edit

    Double = object
      bits*: BitsType

  Source Edit

    FloatingDecimal64 {.bycopy.} = object
      significand*: uint64
      exponent*: int32

  Source Edit

    uint64x2 {.bycopy.} = object
      hi*: uint64
      lo*: uint64

  Source Edit

    ValueType = float

  Source Edit

# Consts

    dtoaMinBufferLength: cint = 64

  Source Edit

    exponentBias: int32 = 1075'i32

  Source Edit

    exponentMask: BitsType = 9218868437227405312'u64

  Source Edit

    hiddenBit: BitsType = 4503599627370496'u64

  Source Edit

    maxIeeeExponent: BitsType = 2047'u

  Source Edit

    significandMask: BitsType = 4503599627370495'u64

  Source Edit

    significandSize: int32 = 53

  Source Edit

    signMask: BitsType = 9223372036854775808'u64

  Source Edit

# Procs

    proc computeDelta(pow10: uint64x2; betaMinus1: int32): uint32 {.inline,
        ...raises: [], tags: [], forbids: [].}

  Source Edit

    proc computePow10(k: int32): uint64x2 {.inline, ...raises: [], tags: [],
                                            forbids: [].}

  Source Edit

    proc constructDouble(bits: BitsType): Double {....raises: [], tags: [], forbids: [].}

  Source Edit

    proc constructDouble(value: ValueType): Double {....raises: [], tags: [],
        forbids: [].}

  Source Edit

    proc decimalLength(v: uint64): int {.inline, ...raises: [], tags: [], forbids: [].}

  Source Edit

    proc floorDivPow2(x: int32; n: int32): int32 {.inline, ...raises: [], tags: [],
        forbids: [].}

  Source Edit

    proc floorLog2Pow10(e: int32): int32 {.inline, ...raises: [], tags: [], forbids: [].}

  Source Edit

    proc floorLog10Pow2(e: int32): int32 {.inline, ...raises: [], tags: [], forbids: [].}

  Source Edit

    proc floorLog10ThreeQuartersPow2(e: int32): int32 {.inline, ...raises: [],
        tags: [], forbids: [].}

  Source Edit

    proc formatDigits[T: Ordinal](buffer: var openArray[char]; pos: T;
                                  digits: uint64; decimalExponent: int;
                                  forceTrailingDotZero = false): int {.inline.}

  Source Edit

    proc hi32(x: uint64): uint32 {.inline, ...raises: [], tags: [], forbids: [].}

  Source Edit

    proc isFinite(this: Double): bool {.noSideEffect, ...raises: [], tags: [],
                                        forbids: [].}

  Source Edit

    proc isInf(this: Double): bool {.noSideEffect, ...raises: [], tags: [], forbids: [].}

  Source Edit

    proc isIntegralEndpoint(twoF: uint64; e2: int32; minusK: int32): bool {.inline,
        ...raises: [], tags: [], forbids: [].}

  Source Edit

    proc isIntegralMidpoint(twoF: uint64; e2: int32; minusK: int32): bool {.inline,
        ...raises: [], tags: [], forbids: [].}

  Source Edit

    proc isNaN(this: Double): bool {.noSideEffect, ...raises: [], tags: [], forbids: [].}

  Source Edit

    proc isZero(this: Double): bool {.noSideEffect, ...raises: [], tags: [],
                                      forbids: [].}

  Source Edit

    proc lo32(x: uint64): uint32 {.inline, ...raises: [], tags: [], forbids: [].}

  Source Edit

    proc mul128(a: uint64; b: uint64): uint64x2 {.inline, ...raises: [], tags: [],
        forbids: [].}

  Source Edit

    proc mulParity(twoF: uint64; pow10: uint64x2; betaMinus1: int32): bool {.inline,
        ...raises: [], tags: [], forbids: [].}

  1 mulx, 1 mul Source Edit

    proc mulShift(x: uint64; y: uint64x2): uint64 {.inline, ...raises: [], tags: [],
        forbids: [].}

  2 mulx Source Edit

    proc multipleOfPow2(value: uint64; e2: int32): bool {.inline, ...raises: [],
        tags: [], forbids: [].}

  Source Edit

    proc multipleOfPow5(value: uint64; e5: int32): bool {.inline, ...raises: [],
        tags: [], forbids: [].}

  Source Edit

    proc physicalExponent(this: Double): BitsType {.noSideEffect, ...raises: [],
        tags: [], forbids: [].}

  Source Edit

    proc physicalSignificand(this: Double): BitsType {.noSideEffect, ...raises: [],
        tags: [], forbids: [].}

  Source Edit

    proc printDecimalDigitsBackwards(buf: var openArray[char]; pos: int;
                                     output64: uint64): int {.inline, ...raises: [],
        tags: [], forbids: [].}

  Source Edit

    proc signBit(this: Double): int {.noSideEffect, ...raises: [], tags: [],
                                      forbids: [].}

  Source Edit

    proc toChars(buffer: var openArray[char]; v: float; forceTrailingDotZero = false): int {.
        inline, ...raises: [], tags: [], forbids: [].}

  Source Edit

    proc toDecimal64(ieeeSignificand: uint64; ieeeExponent: uint64): FloatingDecimal64 {.
        inline, ...raises: [], tags: [], forbids: [].}

  Source Edit

    proc toDecimal64AsymmetricInterval(e2: int32): FloatingDecimal64 {.inline,
        ...raises: [], tags: [], forbids: [].}

  NB: accept_lower_endpoint = true accept_upper_endpoint = true Source Edit

    proc utoa8DigitsSkipTrailingZeros(buf: var openArray[char]; pos: int;
                                      digits: uint32): int {.inline, ...raises: [],
        tags: [], forbids: [].}

  Source Edit

# Templates

    template dragonbox_Assert(x: untyped): untyped

  Source Edit