make -d:nimFpRoundtrips work consistently in vm vs rt, fix #18400, etc (#18531)

* compiler/vmhooks: add getVar to allow vmops with var params
* addFloat vmops with var param
* cgen now renders float32 literals in c backend using roundtrip float to string
This commit is contained in:
Timothee Cour
2021-07-20 13:13:52 -07:00
committed by GitHub
parent a8b3e7c059
commit cf0cf32d27
21 changed files with 286 additions and 199 deletions

View File

@@ -1 +0,0 @@
-d:nimFpRoundtrips

View File

@@ -1,13 +1,14 @@
discard """
matrix: "-d:nimFpRoundtrips; -u:nimFpRoundtrips"
targets: "c cpp js"
"""
# disabled: "windows"
#[
xxx merge all or most float tests into this file
]#
import std/[fenv, math, strutils]
import stdtest/testutils
proc equalsOrNaNs(a, b: float): bool =
if isNaN(a): isNaN(b)
@@ -62,27 +63,103 @@ template main =
reject "1_.0"
reject "1.0_"
block: # bug #18148
var a = 1.1'f32
doAssert $a == "1.1", $a # was failing
block: # bugs mentioned in https://github.com/nim-lang/Nim/pull/18504#issuecomment-881635317
block: # example 1
let a = 0.1+0.2
doAssert a != 0.3
when defined(nimFpRoundtrips):
doAssert $a == "0.30000000000000004"
else:
whenRuntimeJs: discard
do: doAssert $a == "0.3"
block: # example 2
const a = 0.1+0.2
when defined(nimFpRoundtrips):
doAssert $($a, a) == """("0.30000000000000004", 0.30000000000000004)"""
else:
whenRuntimeJs: discard
do: doAssert $($a, a) == """("0.3", 0.3)"""
block: # example 3
const a1 = 0.1+0.2
let a2 = a1
doAssert a1 != 0.3
when defined(nimFpRoundtrips):
doAssert $[$a1, $a2] == """["0.30000000000000004", "0.30000000000000004"]"""
else:
whenRuntimeJs: discard
do: doAssert $[$a1, $a2] == """["0.3", "0.3"]"""
proc runtimeOnlyTests =
# enable for 'static' once -d:nimFpRoundtrips became the default
block: # bug #7717
proc test(f: float) =
let f2 = $f
let f3 = parseFloat(f2)
doAssert equalsOrNaNs(f, f3), $(f, f2, f3)
when defined(nimFpRoundtrips):
block: # bug #18148
var a = 1.1'f32
doAssert $a == "1.1", $a # was failing
test 1.0 + epsilon(float64)
test 1000000.0000000123
test log2(100000.0)
test maximumPositiveValue(float32)
test maximumPositiveValue(float64)
test minimumPositiveValue(float32)
test minimumPositiveValue(float64)
block: # bug #18400
block:
let a1 = 0.1'f32
let a2 = 0.2'f32
let a3 = a1 + a2
var s = ""
s.addFloat(a3)
whenVMorJs: discard # xxx refs #12884
do:
doAssert a3 == 0.3'f32
doAssert $a3 == "0.3"
block:
let a1 = 0.1
let a2 = 0.2
let a3 = a1 + a2
var s = ""
s.addFloat(a3)
doAssert a3 != 0.3
doAssert $a3 == "0.30000000000000004"
block:
var s = [-13.888888'f32]
whenRuntimeJs: discard
do:
doAssert $s == "[-13.888888]"
doAssert $s[0] == "-13.888888"
block: # bug #7717
proc test(f: float) =
let f2 = $f
let f3 = parseFloat(f2)
doAssert equalsOrNaNs(f, f3), $(f, f2, f3)
test 1.0 + epsilon(float64)
test 1000000.0000000123
test log2(100000.0)
test maximumPositiveValue(float32)
test maximumPositiveValue(float64)
test minimumPositiveValue(float32)
test minimumPositiveValue(float64)
block: # bug #12884
block: # example 1
const x0: float32 = 1.32
let x1 = 1.32
let x2 = 1.32'f32
var x3: float32 = 1.32
doAssert $(x0, x1, x2, x3) == "(1.32, 1.32, 1.32, 1.32)"
block: # example https://github.com/nim-lang/Nim/issues/12884#issuecomment-564967962
let x = float(1.32'f32)
when nimvm: discard # xxx prints 1.3
else:
when not defined(js):
doAssert $x == "1.3200000524520874"
doAssert $1.32 == "1.32"
doAssert $1.32'f32 == "1.32"
let x2 = 1.32'f32
doAssert $x2 == "1.32"
block:
var x = 1.23456789012345'f32
when nimvm:
discard # xxx, refs #12884
else:
when not defined(js):
doAssert x == 1.2345679'f32
doAssert $x == "1.2345679"
static: main()
main()
runtimeOnlyTests()