fix #16815 round(x,places) works again in vm (#16825)

* fix #16815 round+places works again in vm

* improve tests; fix for linux 32bit

* fix test for windows
This commit is contained in:
Timothee Cour 2021-01-28 01:40:18 -08:00 • committed by GitHub
commit b0f38a63c4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 41 additions and 29 deletions

View file

@ -41,6 +41,9 @@ template getX(k, field) {.dirty.} =
doAssert a.slots[i+a.rb+1].kind == k doAssert a.slots[i+a.rb+1].kind == k
result = a.slots[i+a.rb+1].field result = a.slots[i+a.rb+1].field
proc numArgs*(a: VmArgs): int =
result = a.rc-1
proc getInt*(a: VmArgs; i: Natural): BiggestInt = getX(rkInt, intVal) proc getInt*(a: VmArgs; i: Natural): BiggestInt = getX(rkInt, intVal)
proc getBool*(a: VmArgs; i: Natural): bool = getInt(a, i) != 0 proc getBool*(a: VmArgs; i: Natural): bool = getInt(a, i) != 0
proc getFloat*(a: VmArgs; i: Natural): BiggestFloat = getX(rkFloat, floatVal) proc getFloat*(a: VmArgs; i: Natural): BiggestFloat = getX(rkFloat, floatVal)

View file

@ -52,6 +52,7 @@ template md5op(op) {.dirty.} =
template wrap1f_math(op) {.dirty.} = template wrap1f_math(op) {.dirty.} =
proc `op Wrapper`(a: VmArgs) {.nimcall.} = proc `op Wrapper`(a: VmArgs) {.nimcall.} =
doAssert a.numArgs == 1
setResult(a, op(getFloat(a, 0))) setResult(a, op(getFloat(a, 0)))
mathop op mathop op
@ -157,7 +158,6 @@ proc registerAdditionalOps*(c: PCtx) =
wrap1f_math(log10) wrap1f_math(log10)
wrap1f_math(log2) wrap1f_math(log2)
wrap1f_math(exp) wrap1f_math(exp)
wrap1f_math(round)
wrap1f_math(arccos) wrap1f_math(arccos)
wrap1f_math(arcsin) wrap1f_math(arcsin)
wrap1f_math(arctan) wrap1f_math(arctan)
@ -180,6 +180,13 @@ proc registerAdditionalOps*(c: PCtx) =
when declared(signbit): when declared(signbit):
wrap1f_math(signbit) wrap1f_math(signbit)
registerCallback c, "stdlib.math.round", proc (a: VmArgs) {.nimcall.} =
let n = a.numArgs
case n
of 1: setResult(a, round(getFloat(a, 0)))
of 2: setResult(a, round(getFloat(a, 0), getInt(a, 1).int))
else: doAssert false, $n
wrap1s(getMD5, md5op) wrap1s(getMD5, md5op)
proc `mod Wrapper`(a: VmArgs) {.nimcall.} = proc `mod Wrapper`(a: VmArgs) {.nimcall.} =

View file

@ -168,14 +168,6 @@ block:
let x: seq[float] = @[] let x: seq[float] = @[]
doAssert prod(x) == 1.0 doAssert prod(x) == 1.0
block: # round() tests
# Round to 0 decimal places
doAssert round(54.652) == 55.0
doAssert round(54.352) == 54.0
doAssert round(-54.652) == -55.0
doAssert round(-54.352) == -54.0
doAssert round(0.0) == 0.0
block: # splitDecimal() tests block: # splitDecimal() tests
doAssert splitDecimal(54.674).intpart == 54.0 doAssert splitDecimal(54.674).intpart == 54.0
doAssert splitDecimal(54.674).floatpart ==~ 0.674 doAssert splitDecimal(54.674).floatpart ==~ 0.674
@ -372,26 +364,36 @@ template main =
doAssert copySign(-NaN, -0.0).isNaN doAssert copySign(-NaN, -0.0).isNaN
block: # round() tests block: # round() tests
# Round to 0 decimal places block: # Round to 0 decimal places
doAssert round(54.652) == 55.0 doAssert round(54.652) == 55.0
doAssert round(54.352) == 54.0 doAssert round(54.352) == 54.0
doAssert round(-54.652) == -55.0 doAssert round(-54.652) == -55.0
doAssert round(-54.352) == -54.0 doAssert round(-54.352) == -54.0
doAssert round(0.0) == 0.0 doAssert round(0.0) == 0.0
doAssert 1 / round(0.0) == Inf doAssert 1 / round(0.0) == Inf
doAssert 1 / round(-0.0) == -Inf doAssert 1 / round(-0.0) == -Inf
doAssert round(Inf) == Inf doAssert round(Inf) == Inf
doAssert round(-Inf) == -Inf doAssert round(-Inf) == -Inf
doAssert round(NaN).isNaN doAssert round(NaN).isNaN
doAssert round(-NaN).isNaN doAssert round(-NaN).isNaN
doAssert round(-0.5) == -1.0 doAssert round(-0.5) == -1.0
doAssert round(0.5) == 1.0 doAssert round(0.5) == 1.0
doAssert round(-1.5) == -2.0 doAssert round(-1.5) == -2.0
doAssert round(1.5) == 2.0 doAssert round(1.5) == 2.0
doAssert round(-2.5) == -3.0 doAssert round(-2.5) == -3.0
doAssert round(2.5) == 3.0 doAssert round(2.5) == 3.0
doAssert round(2.5'f32) == 3.0'f32 doAssert round(2.5'f32) == 3.0'f32
doAssert round(2.5'f64) == 3.0'f64 doAssert round(2.5'f64) == 3.0'f64
block: # func round*[T: float32|float64](x: T, places: int): T
doAssert round(54.345, 0) == 54.0
template fn(x) =
doAssert round(x, 2).almostEqual 54.35
doAssert round(x, 2).almostEqual 54.35
doAssert round(x, -1).almostEqual 50.0
doAssert round(x, -2).almostEqual 100.0
doAssert round(x, -3).almostEqual 0.0
fn(54.346)
fn(54.346'f32)
when nimvm: when nimvm:
discard discard