Skip to content

Instantly share code, notes, and snippets.

@timotheecour
Created May 25, 2021 22:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save timotheecour/b80666a4ba360f3473548db7ad298cfc to your computer and use it in GitHub Desktop.
Save timotheecour/b80666a4ba360f3473548db7ad298cfc to your computer and use it in GitHub Desktop.
c2nim --cpp dragonbox.cc
## 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.
var DtoaMinBufferLength*: cint = 64
proc Dtoa*(buffer: cstring; value: cdouble): cstring
## namespace dragonbox
## --------------------------------------------------------------------------------------------------
## 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.
## --------------------------------------------------------------------------------------------------
when defined(_MSC_VER):
discard
when not defined(DRAGONBOX_ASSERT):
template DRAGONBOX_ASSERT*(X: untyped): untyped =
assert(X)
## ==================================================================================================
##
## ==================================================================================================
proc ReinterpretBits*[Dest; Source](source: Source): Dest =
discard
type
Double* {.bycopy.} = object
bits*: bits_type ## = p (includes the hidden bit)
## static constexpr int32_t MaxExponent = std::numeric_limits<value_type>::max_exponent - 1 - (SignificandSize - 1);
## static constexpr int32_t MinExponent = std::numeric_limits<value_type>::min_exponent - 1 - (SignificandSize - 1);
## = 2^(p-1)
## = 2^(p-1) - 1
## !!!Ignored construct: static_assert ( std :: numeric_limits < double > :: is_iec559 && std :: numeric_limits < double > :: digits == 53 && std :: numeric_limits < double > :: max_exponent == 1024 , IEEE-754 double-precision implementation required ) ;
## Error: token expected: ) but got: ::!!!
type
value_type* = cdouble
bits_type* = uint64_t
proc constructDouble*(bits_: bits_type): Double {.constructor.}
proc constructDouble*(value: value_type): Double {.constructor.}
proc PhysicalSignificand*(this: Double): bits_type {.noSideEffect.}
proc PhysicalExponent*(this: Double): bits_type {.noSideEffect.}
proc IsFinite*(this: Double): bool {.noSideEffect.}
proc IsInf*(this: Double): bool {.noSideEffect.}
proc IsNaN*(this: Double): bool {.noSideEffect.}
proc IsZero*(this: Double): bool {.noSideEffect.}
proc SignBit*(this: Double): bool {.noSideEffect.}
## namespace
## ==================================================================================================
##
## ==================================================================================================
## Returns floor(x / 2^n).
##
## Technically, right-shift of negative integers is implementation defined...
## Should easily be optimized into SAR (or equivalent) instruction.
proc FloorDivPow2*(x: int32_t; n: int32_t): int32_t =
discard
proc FloorLog2Pow10*(e: int32_t): int32_t =
discard
proc FloorLog10Pow2*(e: int32_t): int32_t =
discard
proc FloorLog10ThreeQuartersPow2*(e: int32_t): int32_t =
discard
## ==================================================================================================
##
## ==================================================================================================
type
uint64x2* {.bycopy.} = object
hi*: uint64_t
lo*: uint64_t
proc ComputePow10*(k: int32_t): uint64x2 =
discard
## Returns whether value is divisible by 2^e2
proc MultipleOfPow2*(value: uint64_t; e2: int32_t): bool =
discard
## Returns whether value is divisible by 5^e5
proc MultipleOfPow5*(value: uint64_t; e5: int32_t): bool =
discard
type
FloatingDecimal64* {.bycopy.} = object
significand*: uint64_t
exponent*: int32_t
proc ToDecimal64_asymmetric_interval*(e2: int32_t): FloatingDecimal64 =
discard
proc ComputeDelta*(pow10: uint64x2; beta_minus_1: int32_t): uint32_t =
discard
when defined(__SIZEOF_INT128__):
proc Mul128*(x: uint64_t; y: uint64_t): uint64x2 =
## 1 mulx
discard
elif defined(_MSC_VER) and defined(_M_X64):
proc Mul128*(x: uint64_t; y: uint64_t): uint64x2 =
discard
else:
proc Lo32*(x: uint64_t): uint32_t =
discard
proc Hi32*(x: uint64_t): uint32_t =
discard
proc Mul128*(a: uint64_t; b: uint64_t): uint64x2 =
discard
## Returns (x * y) / 2^128
proc MulShift*(x: uint64_t; y: uint64x2): uint64_t =
## 2 mulx
discard
proc MulParity*(two_f: uint64_t; pow10: uint64x2; beta_minus_1: int32_t): bool =
## 1 mulx, 1 mul
discard
proc IsIntegralEndpoint*(two_f: uint64_t; e2: int32_t; minus_k: int32_t): bool =
discard
proc IsIntegralMidpoint*(two_f: uint64_t; e2: int32_t; minus_k: int32_t): bool =
discard
proc ToDecimal64*(ieee_significand: uint64_t; ieee_exponent: uint64_t): FloatingDecimal64 =
discard
## ==================================================================================================
## ToChars
## ==================================================================================================
proc Utoa_2Digits*(buf: cstring; digits: uint32_t) =
discard
proc TrailingZeros_2Digits*(digits: uint32_t): int32_t =
discard
proc Utoa_8Digits_skip_trailing_zeros*(buf: cstring; digits: uint32_t): int32_t =
discard
proc PrintDecimalDigitsBackwards*(buf: cstring; output64: uint64_t): int32_t =
discard
proc DecimalLength*(v: uint64_t): int32_t =
discard
proc FormatDigits*(buffer: cstring; digits: uint64_t; decimal_exponent: int32_t;
force_trailing_dot_zero: bool = false): cstring =
discard
proc ToChars*(buffer: cstring; value: cdouble; force_trailing_dot_zero: bool = false): cstring =
discard
## ==================================================================================================
##
## ==================================================================================================
proc Dtoa*(buffer: cstring; value: cdouble): cstring
proc nim_dragonbox_Dtoa*(buffer: cstring; value: cdouble): cstring =
discard
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment