* use dragonbox algorithm; alternative to #18008 * removed unsafe code
This commit is contained in:
parent
ba3ec7b049
commit
63db2b19bf
5 changed files with 1408 additions and 50 deletions
|
|
@ -76,6 +76,10 @@
|
||||||
- `json` and `jsonutils` now serialize NaN, Inf, -Inf as strings, so that
|
- `json` and `jsonutils` now serialize NaN, Inf, -Inf as strings, so that
|
||||||
`%[NaN, -Inf]` is the string `["nan","-inf"]` instead of `[nan,-inf]` which was invalid json.
|
`%[NaN, -Inf]` is the string `["nan","-inf"]` instead of `[nan,-inf]` which was invalid json.
|
||||||
|
|
||||||
|
- `system.addFloat` now uses the "Dragonbox" algorithm, which ensures correct roundtrips of floating point
|
||||||
|
numbers, that the minimum length representation of a floating point number is used and correct rounding.
|
||||||
|
Use `-d:nimLegacyAddFloat` for a transition period.
|
||||||
|
|
||||||
- `strformat` is now part of `include std/prelude`.
|
- `strformat` is now part of `include std/prelude`.
|
||||||
|
|
||||||
- Deprecated `proc reversed*[T](a: openArray[T], first: Natural, last: int): seq[T]` in `std/algorithm`.
|
- Deprecated `proc reversed*[T](a: openArray[T], first: Natural, last: int): seq[T]` in `std/algorithm`.
|
||||||
|
|
|
||||||
|
|
@ -134,3 +134,5 @@ proc initDefines*(symbols: StringTableRef) =
|
||||||
defineSymbol("nimHasUnifiedTuple")
|
defineSymbol("nimHasUnifiedTuple")
|
||||||
defineSymbol("nimHasIterable")
|
defineSymbol("nimHasIterable")
|
||||||
defineSymbol("nimHasTypeofVoid")
|
defineSymbol("nimHasTypeofVoid")
|
||||||
|
|
||||||
|
defineSymbol("nimHasDragonBox")
|
||||||
|
|
|
||||||
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,28 +7,33 @@
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
#
|
#
|
||||||
|
|
||||||
proc c_sprintf(buf, frmt: cstring): cint {.header: "<stdio.h>",
|
when not defined(nimLegacyAddFloat) and not defined(nimscript) and
|
||||||
|
not defined(js) and defined(nimHasDragonBox):
|
||||||
|
import dragonbox
|
||||||
|
|
||||||
|
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'
|
||||||
|
|
||||||
|
else:
|
||||||
|
proc c_sprintf(buf, frmt: cstring): cint {.header: "<stdio.h>",
|
||||||
importc: "sprintf", varargs, noSideEffect.}
|
importc: "sprintf", varargs, noSideEffect.}
|
||||||
|
|
||||||
proc writeToBuffer(buf: var array[65, char]; value: cstring) =
|
proc writeToBuffer(buf: var array[65, char]; value: cstring) =
|
||||||
var i = 0
|
var i = 0
|
||||||
while value[i] != '\0':
|
while value[i] != '\0':
|
||||||
buf[i] = value[i]
|
buf[i] = value[i]
|
||||||
inc i
|
inc i
|
||||||
|
|
||||||
proc writeFloatToBuffer*(buf: var array[65, char]; value: BiggestFloat): int =
|
proc writeFloatToBuffer*(buf: var array[65, char]; value: BiggestFloat): int =
|
||||||
## This is the implementation to format floats in the Nim
|
## This is the implementation to format floats.
|
||||||
## 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
|
## returns the amount of bytes written to `buf` not counting the
|
||||||
## terminating '\0' character.
|
## 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 n: int = c_sprintf(addr buf, "%.16g", value)
|
||||||
var hasDot = false
|
var hasDot = false
|
||||||
for i in 0..n-1:
|
for i in 0..n-1:
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
discard """
|
discard """
|
||||||
output: '''
|
output: '''
|
||||||
1e-06 : 1e-06
|
0.000001 : 0.000001
|
||||||
1e-06 : 1e-06
|
0.000001 : 0.000001
|
||||||
0.001 : 0.001
|
0.001 : 0.001
|
||||||
1e-06 : 1e-06
|
0.000001 : 0.000001
|
||||||
1e-06 : 1e-06
|
0.000001 : 0.000001
|
||||||
10.000001 : 10.000001
|
10.000001 : 10.000001
|
||||||
100.000001 : 100.000001
|
100.000001 : 100.000001
|
||||||
'''
|
'''
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue