mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-19 14:00:35 +00:00
* use dragonbox algorithm; alternative to #18008 * removed unsafe code
This commit is contained in:
1347
lib/system/dragonbox.nim
Normal file
1347
lib/system/dragonbox.nim
Normal file
File diff suppressed because it is too large
Load Diff
@@ -7,53 +7,58 @@
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
proc c_sprintf(buf, frmt: cstring): cint {.header: "<stdio.h>",
|
||||
importc: "sprintf", varargs, noSideEffect.}
|
||||
when not defined(nimLegacyAddFloat) and not defined(nimscript) and
|
||||
not defined(js) and defined(nimHasDragonBox):
|
||||
import dragonbox
|
||||
|
||||
proc writeToBuffer(buf: var array[65, char]; value: cstring) =
|
||||
var i = 0
|
||||
while value[i] != '\0':
|
||||
buf[i] = value[i]
|
||||
inc i
|
||||
proc writeFloatToBuffer*(buf: var array[65, char]; value: BiggestFloat): int =
|
||||
## This is the implementation to format floats.
|
||||
##
|
||||
## returns the amount of bytes written to `buf` not counting the
|
||||
## terminating '\0' character.
|
||||
result = toChars(buf, value, forceTrailingDotZero=true)
|
||||
buf[result] = '\0'
|
||||
|
||||
proc writeFloatToBuffer*(buf: var array[65, char]; value: BiggestFloat): int =
|
||||
## This is the implementation to format floats in the Nim
|
||||
## programming language. The specific format for floating point
|
||||
## numbers is not specified in the Nim programming language and
|
||||
## might change slightly in the future, but at least wherever you
|
||||
## format a float, it should be consistent.
|
||||
##
|
||||
## returns the amount of bytes written to `buf` not counting the
|
||||
## terminating '\0' character.
|
||||
##
|
||||
## * `buf` - A buffer to write into. The buffer does not need to be
|
||||
## initialized and it will be overridden.
|
||||
##
|
||||
var n: int = c_sprintf(addr buf, "%.16g", value)
|
||||
var hasDot = false
|
||||
for i in 0..n-1:
|
||||
if buf[i] == ',':
|
||||
buf[i] = '.'
|
||||
hasDot = true
|
||||
elif buf[i] in {'a'..'z', 'A'..'Z', '.'}:
|
||||
hasDot = true
|
||||
if not hasDot:
|
||||
buf[n] = '.'
|
||||
buf[n+1] = '0'
|
||||
buf[n+2] = '\0'
|
||||
result = n + 2
|
||||
else:
|
||||
result = n
|
||||
# On Windows nice numbers like '1.#INF', '-1.#INF' or '1.#NAN' or 'nan(ind)'
|
||||
# of '-1.#IND' are produced.
|
||||
# We want to get rid of these here:
|
||||
if buf[n-1] in {'n', 'N', 'D', 'd', ')'}:
|
||||
writeToBuffer(buf, "nan")
|
||||
result = 3
|
||||
elif buf[n-1] == 'F':
|
||||
if buf[0] == '-':
|
||||
writeToBuffer(buf, "-inf")
|
||||
result = 4
|
||||
else:
|
||||
proc c_sprintf(buf, frmt: cstring): cint {.header: "<stdio.h>",
|
||||
importc: "sprintf", varargs, noSideEffect.}
|
||||
|
||||
proc writeToBuffer(buf: var array[65, char]; value: cstring) =
|
||||
var i = 0
|
||||
while value[i] != '\0':
|
||||
buf[i] = value[i]
|
||||
inc i
|
||||
|
||||
proc writeFloatToBuffer*(buf: var array[65, char]; value: BiggestFloat): int =
|
||||
## This is the implementation to format floats.
|
||||
##
|
||||
## returns the amount of bytes written to `buf` not counting the
|
||||
## terminating '\0' character.
|
||||
var n: int = c_sprintf(addr buf, "%.16g", value)
|
||||
var hasDot = false
|
||||
for i in 0..n-1:
|
||||
if buf[i] == ',':
|
||||
buf[i] = '.'
|
||||
hasDot = true
|
||||
elif buf[i] in {'a'..'z', 'A'..'Z', '.'}:
|
||||
hasDot = true
|
||||
if not hasDot:
|
||||
buf[n] = '.'
|
||||
buf[n+1] = '0'
|
||||
buf[n+2] = '\0'
|
||||
result = n + 2
|
||||
else:
|
||||
writeToBuffer(buf, "inf")
|
||||
result = n
|
||||
# On Windows nice numbers like '1.#INF', '-1.#INF' or '1.#NAN' or 'nan(ind)'
|
||||
# of '-1.#IND' are produced.
|
||||
# We want to get rid of these here:
|
||||
if buf[n-1] in {'n', 'N', 'D', 'd', ')'}:
|
||||
writeToBuffer(buf, "nan")
|
||||
result = 3
|
||||
elif buf[n-1] == 'F':
|
||||
if buf[0] == '-':
|
||||
writeToBuffer(buf, "-inf")
|
||||
result = 4
|
||||
else:
|
||||
writeToBuffer(buf, "inf")
|
||||
result = 3
|
||||
|
||||
Reference in New Issue
Block a user