Hello Nim people, during a long and boring train trip I ported Milo Yip's fast
dtoa implementation to Nim. A quick & precise benchmark using criterion.nim
(shameless plug) shows that it is ~5 times faster than the plain old $
(1.8231us vs 9.4357us on my machine) and should be pretty useful for
Nice, pure Nim implementation. We should patch the stdlib to use this
implementation...
Can this be part of v0.19 pretty please?
("5 time faster float to string conversion" would look really nice in the
release notes :))
Fantastic news, let's get it to stdlib. But I think it needs more correctness
tests. I would run a test that converts every represtantable float into string
and back and compare they are exactly the same. We had problems in the past
with parseBiggestFloat due lack of tests
> But I think it needs more correctness tests.
Indeed!
My quick and dirty test showed these results:
[fraction = $result: dtoa(result)]
7 / 3 = 2.333: 2.3337
10 / 3 = 3.333: 3.3337
7 / 6 = 1.167: 1.1666
If I add better support for float to it, quicktest can help with generating
those tests
Nice :)
btw, I don't like the libc functions, which are currently used in strutils,
because it produces unexpected output for some numbers, example:
formatFloat(65000.45, ffDecimal) = 65000.44970896
Run
With ffDefault it's ok, but it will switch to scientific
Nice! Your dtoa passed my quick pseudorandom number test.
import ./src/dtoa
import math, parseutils, random
proc test0(v: float64) =
let s = dtoa(v)
var v2:float64
doAssert parseBiggestFloat(s, v2) != 0
doAssert v2 == v
proc test(v: float6
The underlying algorithm is nothing more than `grisu2` that's going to give you
roundtrip-able values in the shortest amount of time, the tradeoff is in the
0.05% of numbers that cannot be "encoded" in the shortest possible way.
For a stdlib implementation you may want to use something like `err