From 385aaf57e80e33922b8156b2d8b8621df3e03231 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 | 11 ++++++----- tests/test1.nim | 4 ++++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/parsetoml.nim b/src/parsetoml.nim index 8993d64..a6cd113 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,11 +273,10 @@ 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: wasUnderscore = nextChar == '_' nextChar = state.getNextChar() @@ -293,11 +294,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..d4c0120 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