From 3e4c2da755dad1be0881f36f1a9067e6349821f3 Mon Sep 17 00:00:00 2001 From: Kaushal Modi Date: Sun, 6 Jun 2021 22:31:22 -0400 Subject: [PATCH] Fix float-parsing logic With the float string representation fixed in Nim devel (See https://github.com/nim-lang/Nim/pull/18139), that uncovered a bug in the logic for parsing float TOML values. For e.g. to parse "foo = 0.123", internally, 0.1 + 0.02 + 0.003 was done which would evaluate to 0.12300000000000001. Earlier float stringification bug caused that value to print out as "0.123" instead of "0.12300000000000001". This is now fixed by using parseutils.parsefloat, which parses the "0.123" float value as 0.123 and not 0.12300000000000001. Fixes https://github.com/NimParsers/parsetoml/issues/45. --- src/parsetoml.nim | 10 ++++++---- tests/test1.nim | 4 ++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/parsetoml.nim b/src/parsetoml.nim index 8993d64..65ef7ef 100644 --- a/src/parsetoml.nim +++ b/src/parsetoml.nim @@ -36,6 +36,8 @@ import streams import strutils import tables import unicode +from parseutils import parseFloat + export tables when (NimMajor, NimMinor, NimPatch) < (1, 4, 0): @@ -271,9 +273,9 @@ proc parseEncoding(state: var ParserState): TomlValueRef = proc parseDecimalPart(state: var ParserState): float64 = var nextChar: char - invPowerOfTen = 10.0 firstPos = true wasUnderscore = false + decimalPartStr = "0." result = 0.0 while true: @@ -293,11 +295,11 @@ proc parseDecimalPart(state: var ParserState): float64 = raise newTomlError(state, "decimal part empty") break - result = result + (int(nextChar) - int('0')).float / invPowerOfTen - invPowerOfTen *= 10 + decimalPartStr.add(nextChar) firstPos = false - + doAssert decimalPartStr.len > 2 # decimalPartStr shouldn't still be "0." at this point + discard parseutils.parseFloat(decimalPartStr, result) proc stringDelimiter(kind: StringType): char {.inline, noSideEffect.} = result = (case kind diff --git a/tests/test1.nim b/tests/test1.nim index 5de12e3..b234d18 100644 --- a/tests/test1.nim +++ b/tests/test1.nim @@ -95,3 +95,7 @@ file_name = "test.txt" tomlRef.setEmptyTableVal() check: tomlRef.kind == TomlValueKind.Table + +suite "bug fixes": + test "issue-45": + check $("some_float = 0.123".parseString()["some_float"].getFloat()) == "0.123"