summary refs log tree commit diff stats
path: root/tests/float
diff options
context:
space:
mode:
Diffstat (limited to 'tests/float')
-rw-r--r--tests/float/tfloat1.nim12
-rw-r--r--tests/float/tfloat2.nim12
-rw-r--r--tests/float/tfloat3.nim21
-rw-r--r--tests/float/tfloat4.nim69
-rw-r--r--tests/float/tfloat5.nim16
-rw-r--r--tests/float/tfloat7.nim27
-rw-r--r--tests/float/tfloatmod.nim130
-rw-r--r--tests/float/tfloatnan.nim57
-rw-r--r--tests/float/tfloatrange.nim50
-rw-r--r--tests/float/tfloats.nim163
-rw-r--r--tests/float/tissue5821.nim15
-rw-r--r--tests/float/tlenientops.nim100
12 files changed, 672 insertions, 0 deletions
diff --git a/tests/float/tfloat1.nim b/tests/float/tfloat1.nim
new file mode 100644
index 000000000..d3497f24c
--- /dev/null
+++ b/tests/float/tfloat1.nim
@@ -0,0 +1,12 @@
+discard """
+  outputsub: "Error: unhandled exception: FPU operation caused an overflow [FloatOverflowDefect]"
+  exitcode: "1"
+"""
+# Test new floating point exceptions
+
+{.floatChecks: on.}
+
+var x = 0.8
+var y = 0.0
+
+echo x / y #OUT Error: unhandled exception: FPU operation caused an overflow
diff --git a/tests/float/tfloat2.nim b/tests/float/tfloat2.nim
new file mode 100644
index 000000000..1de63dde3
--- /dev/null
+++ b/tests/float/tfloat2.nim
@@ -0,0 +1,12 @@
+discard """
+  outputsub: "Error: unhandled exception: FPU operation caused a NaN result [FloatInvalidOpDefect]"
+  exitcode: "1"
+"""
+# Test new floating point exceptions
+
+{.floatChecks: on.}
+
+var x = 0.0
+var y = 0.0
+
+echo x / y #OUT Error: unhandled exception: FPU operation caused a NaN result
diff --git a/tests/float/tfloat3.nim b/tests/float/tfloat3.nim
new file mode 100644
index 000000000..215470cfc
--- /dev/null
+++ b/tests/float/tfloat3.nim
@@ -0,0 +1,21 @@
+discard """
+  output: '''
+Nim 3.4368930843, 0.3299290698
+C double: 3.4368930843, 0.3299290698'''
+"""
+
+import math, strutils
+
+{.emit: """
+void printFloats(void) {
+  double y = 1.234567890123456789;
+  printf("C double: %.10f, %.10f\n", exp(y), cos(y));
+}
+""".}
+
+proc c_printf(frmt: cstring) {.importc: "printf", header: "<stdio.h>", varargs.}
+proc printFloats {.importc, nodecl.}
+
+var x: float = 1.234567890123456789
+c_printf("Nim %.10f, %.10f\n", exp(x), cos(x))
+printFloats()
diff --git a/tests/float/tfloat4.nim b/tests/float/tfloat4.nim
new file mode 100644
index 000000000..2bb61eb58
--- /dev/null
+++ b/tests/float/tfloat4.nim
@@ -0,0 +1,69 @@
+discard """
+  output: "passed all tests."
+"""
+
+import strutils
+
+proc c_sprintf(buf, fmt: cstring) {.importc:"sprintf", header: "<stdio.h>", varargs.}
+
+proc floatToStr(f: float64): string =
+  var buffer: array[128, char]
+  c_sprintf(cast[cstring](addr buffer), "%.16e", f)
+  result = ""
+  for ch in buffer:
+    if ch == '\0':
+      return
+    add(result, ch)
+
+
+let testFloats = [
+  "0", "-0", "0.", "0.0", "-0.", "-0.0", "-1", "1", "1.", ".3", "3.3", "-.3", "-99.99",
+  "1.1e10", "-2e100", "1.234e-10", "1.234e+10",
+  "-inf", "inf", "+inf",
+  "3.14159265358979323846264338327950288",
+  "1.57079632679489661923132169163975144",
+  "0.785398163397448309615660845819875721",
+  "1.41421356237309504880168872420969808",
+  "0.707106781186547524400844362104849039",
+  "2.71828182845904523536028747135266250",
+  "0.00097656250000000021684043449710088680149056017398834228515625"
+]
+
+when not defined(windows):
+  # Windows' sprintf produces niceties like -1.#INF...
+  for num in testFloats:
+    doAssert num.parseFloat.floatToStr.parseFloat == num.parseFloat
+
+doAssert "0".parseFloat == 0.0
+doAssert "-.1".parseFloat == -0.1
+doAssert "2.5e1".parseFloat == 25.0
+doAssert "1e10".parseFloat == 10_000_000_000.0
+doAssert "0.000_005".parseFloat == 5.000_000e-6
+doAssert "1.234_567e+2".parseFloat == 123.4567
+doAssert "1e1_00".parseFloat == "1e100".parseFloat
+doAssert "3.1415926535897932384626433".parseFloat ==
+       3.1415926535897932384626433
+doAssert "2.71828182845904523536028747".parseFloat ==
+       2.71828182845904523536028747
+doAssert 0.00097656250000000021684043449710088680149056017398834228515625 ==
+     "0.00097656250000000021684043449710088680149056017398834228515625".parseFloat
+doAssert 0.00998333 == ".00998333".parseFloat
+doAssert 0.00128333 == ".00128333".parseFloat
+doAssert 999999999999999.0 == "999999999999999.0".parseFloat
+doAssert 9999999999999999.0 == "9999999999999999.0".parseFloat
+doAssert 0.999999999999999 == ".999999999999999".parseFloat
+doAssert 0.9999999999999999 == ".9999999999999999".parseFloat
+
+# bug #18400
+var s = [-13.888888'f32]
+doAssert $s[0] == "-13.888888"
+var x = 1.23456789012345'f32
+doAssert $x == "1.2345679"
+
+# bug #21847
+doAssert parseFloat"0e+42" == 0.0
+doAssert parseFloat"0e+42949672969" == 0.0
+doAssert parseFloat"0e+42949672970" == 0.0
+doAssert parseFloat"0e+42949623223346323563272970" == 0.0
+
+echo("passed all tests.")
diff --git a/tests/float/tfloat5.nim b/tests/float/tfloat5.nim
new file mode 100644
index 000000000..0708838fc
--- /dev/null
+++ b/tests/float/tfloat5.nim
@@ -0,0 +1,16 @@
+discard """
+output: '''
+0 : 0.0
+0 : 0.0
+0 : 0.0
+0 : 0.0
+'''
+"""
+
+import parseutils
+
+var f: float
+echo "*".parseFloat(f), " : ", f
+echo "/".parseFloat(f), " : ", f
+echo "+".parseFloat(f), " : ", f
+echo "-".parseFloat(f), " : ", f
diff --git a/tests/float/tfloat7.nim b/tests/float/tfloat7.nim
new file mode 100644
index 000000000..a6d7af10b
--- /dev/null
+++ b/tests/float/tfloat7.nim
@@ -0,0 +1,27 @@
+discard """
+output: '''
+passed.
+passed.
+passed.
+passed.
+passed.
+passed.
+passed.
+'''
+"""
+
+import strutils
+template expect_fail(x) =
+  try:
+    discard x
+    echo("expected to fail!")
+  except ValueError:
+    echo("passed.")
+
+expect_fail("1_0._00_0001".parseFloat())
+expect_fail("_1_0_00.0001".parseFloat())
+expect_fail("10.00.01".parseFloat())
+expect_fail("10.00E_01".parseFloat())
+expect_fail("10.00E_01".parseFloat())
+expect_fail("10.00E".parseFloat())
+expect_fail("10.00A".parseFloat())
diff --git a/tests/float/tfloatmod.nim b/tests/float/tfloatmod.nim
new file mode 100644
index 000000000..37546a64c
--- /dev/null
+++ b/tests/float/tfloatmod.nim
@@ -0,0 +1,130 @@
+discard """
+  targets: "c cpp js"
+  output: "ok"
+  exitcode: "0"
+"""
+
+# Test `mod` on float64 both at compiletime and at runtime
+import math
+
+# Testdata from golang
+const testValues: array[10, tuple[f64, expected: float64]] = [
+  (4.9790119248836735e+00, 4.197615023265299782906368e-02),
+  (7.7388724745781045e+00, 2.261127525421895434476482e+00),
+  (-2.7688005719200159e-01, 3.231794108794261433104108e-02),
+  (-5.0106036182710749e+00, 4.989396381728925078391512e+00),
+  (9.6362937071984173e+00, 3.637062928015826201999516e-01),
+  (2.9263772392439646e+00, 1.220868282268106064236690e+00),
+  (5.2290834314593066e+00, 4.770916568540693347699744e+00),
+  (2.7279399104360102e+00, 1.816180268691969246219742e+00),
+  (1.8253080916808550e+00, 8.734595415957246977711748e-01),
+  (-8.6859247685756013e+00, 1.314075231424398637614104e+00)]
+
+const simpleTestData = [
+  (5.0, 3.0, 2.0),
+  (5.0, -3.0, 2.0),
+  (-5.0, 3.0, -2.0),
+  (-5.0, -3.0, -2.0),
+  (10.0, 1.0, 0.0),
+  (10.0, 0.5, 0.0),
+  (10.0, 1.5, 1.0),
+  (-10.0, 1.0, -0.0),
+  (-10.0, 0.5, -0.0),
+  (-10.0, 1.5, -1.0),
+  (1.5, 1.0, 0.5),
+  (1.25, 1.0, 0.25),
+  (1.125, 1.0, 0.125)
+  ]
+
+const specialCases = [
+  (-Inf, -Inf, Nan),
+  (-Inf, -Pi, Nan),
+  (-Inf, 0.0, Nan),
+  (-Inf, Pi, Nan),
+  (-Inf, Inf, Nan),
+  (-Inf, Nan, Nan),
+  (-PI, -Inf, -PI),
+  (-PI, 0.0, Nan),
+  (-PI, Inf, -PI),
+  (-PI, Nan, Nan),
+  (-0.0, -Inf, -0.0),
+  (-0.0, 0.0, Nan),
+  (-0.0, Inf, -0.0),
+  (-0.0, Nan, Nan),
+  (0.0, -Inf, 0.0),
+  (0.0, 0.0, Nan),
+  (0.0, Inf, 0.0),
+  (0.0, Nan, Nan),
+  (PI, -Inf, PI),
+  (PI, 0.0, Nan),
+  (PI, Inf, PI),
+  (PI, Nan, Nan),
+  (Inf, -Inf, Nan),
+  (Inf, -PI, Nan),
+  (Inf, 0.0, Nan),
+  (Inf, PI, Nan),
+  (Inf, Inf, Nan),
+  (Inf, Nan, Nan),
+  (Nan, -Inf, Nan),
+  (Nan, -PI, Nan),
+  (Nan, 0.0, Nan),
+  (Nan, PI, Nan),
+  (Nan, Inf, Nan),
+  (Nan, Nan, Nan)]
+
+const extremeValues = [
+  (5.9790119248836734e+200, 1.1258465975523544, 0.6447968302508578),
+  (1.0e-100, 1.0e100, 1.0e-100)]
+
+proc errmsg(x, y, r, expected: float64): string =
+  $x & " mod " & $y & " == " & $r & " but expected " & $expected
+
+proc golangtest() =
+  let x = 10.0
+  for tpl in testValues:
+    let (y, expected) = tpl
+    let r = x mod y
+    doAssert(r == expected, errmsg(x, y, r, expected))
+
+proc simpletest() =
+  for tpl in simpleTestData:
+    let(x, y, expected) = tpl
+    let r = x mod y
+    doAssert(r == expected, errmsg(x, y, r, expected))
+
+proc testSpecialCases() =
+  proc isnan(f: float64): bool =
+    case classify(f)
+    of fcNan:
+      result = true
+    else:
+      result = false
+
+  for tpl in specialCases:
+    let(x, y, expected) = tpl
+    let r = x mod y
+    doAssert((r == expected) or (r.isnan and expected.isnan),
+              errmsg(x, y, r, expected))
+
+proc testExtremeValues() =
+  for tpl in extremeValues:
+    let (x, y, expected) = tpl
+    let r = x mod y
+    doAssert(r == expected, errmsg(x, y, r, expected))
+
+static:
+  # compiletime evaluation
+  golangtest()
+  simpletest()
+  testSpecialCases()
+  testExtremeValues()
+
+proc main() =
+  # runtime evaluation
+  golangtest()
+  simpletest()
+  testSpecialCases()
+  testExtremeValues()
+
+main()
+echo "ok"
diff --git a/tests/float/tfloatnan.nim b/tests/float/tfloatnan.nim
new file mode 100644
index 000000000..9e3dd94f6
--- /dev/null
+++ b/tests/float/tfloatnan.nim
@@ -0,0 +1,57 @@
+discard """
+output: '''
+Nim: nan
+Nim: nan (float)
+Nim: nan (double)
+'''
+"""
+
+let f = NaN
+echo "Nim: ", f
+
+let f32: float32 = NaN
+echo "Nim: ", f32, " (float)"
+
+let f64: float64 = NaN
+echo "Nim: ", f64, " (double)"
+
+block: # bug #10305
+  # with `-O3 -ffast-math`, generated C/C++ code is not nan compliant
+  # user can pass `--passC:-ffast-math` if he doesn't care.
+  proc fun() =
+    # this was previously failing at compile time with a nim compiler
+    # that was compiled with `nim cpp -d:release`
+    let a1 = 0.0
+    let a = 0.0/a1
+    let b1 = a == 0.0
+    let b2 = a == a
+    doAssert not b1
+    doAssert not b2
+
+  proc fun2(i: int) =
+    # this was previously failing simply with `nim cpp -d:release`; the
+    # difference with above example is that optimization (const folding) can't
+    # take place in this example to hide the non-compliant nan bug.
+    let a = 0.0/(i.float)
+    let b1 = a == 0.0
+    let b2 = a == a
+    doAssert not b1
+    doAssert not b2
+
+  static: fun()
+  fun()
+  fun2(0)
+
+template main() =
+  # xxx move all tests under here
+  block: # bug #16469
+    let a1 = 0.0
+    let a2 = -0.0
+    let a3 = 1.0 / a1
+    let a4 = 1.0 / a2
+    doAssert a3 == Inf
+    doAssert a4 == -Inf
+    doAssert $(a1, a2, a3, a4) == "(0.0, -0.0, inf, -inf)"
+
+static: main()
+main()
diff --git a/tests/float/tfloatrange.nim b/tests/float/tfloatrange.nim
new file mode 100644
index 000000000..d345166f4
--- /dev/null
+++ b/tests/float/tfloatrange.nim
@@ -0,0 +1,50 @@
+discard """
+  cmd: "nim c -d:release --rangeChecks:on $file"
+  disabled: "windows"
+  output: '''StrictPositiveRange
+float
+range fail expected
+range fail expected
+'''
+"""
+import math, fenv
+
+type
+  Positive = range[0.0..Inf]
+  StrictPositive = range[minimumPositiveValue(float)..Inf]
+  Negative32 = range[-maximumPositiveValue(float32) .. -1.0'f32]
+
+proc myoverload(x: float) =
+  echo "float"
+
+proc myoverload(x: Positive) =
+  echo "PositiveRange"
+
+proc myoverload(x: StrictPositive) =
+  echo "StrictPositiveRange"
+
+let x = 9.0.StrictPositive
+myoverload(x)
+myoverload(9.0)
+
+doAssert(sqrt(x) == 3.0)
+
+var z = -10.0
+try:
+  myoverload(StrictPositive(z))
+except:
+  echo "range fail expected"
+
+
+proc strictOnlyProc(x: StrictPositive): bool =
+  if x > 1.0: true else: false
+
+let x2 = 5.0.Positive
+doAssert(strictOnlyProc(x2))
+
+try:
+  let x4 = 0.0.Positive
+  discard strictOnlyProc(x4)
+except:
+  echo "range fail expected"
+
diff --git a/tests/float/tfloats.nim b/tests/float/tfloats.nim
new file mode 100644
index 000000000..aaed2d615
--- /dev/null
+++ b/tests/float/tfloats.nim
@@ -0,0 +1,163 @@
+discard """
+  matrix: "-d:nimPreviewFloatRoundtrip; -u:nimPreviewFloatRoundtrip"
+  targets: "c cpp js"
+"""
+
+#[
+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)
+  elif a == 0:
+    b == 0 and signbit(a) == signbit(b)
+  else:
+    a == b
+
+template reject(a) =
+  doAssertRaises(ValueError): discard parseFloat(a)
+
+template main =
+  block:
+    proc test(a: string, b: float) =
+      let a2 = a.parseFloat
+      doAssert equalsOrNaNs(a2, b), $(a, a2, b)
+    test "0.00_0001", 1E-6
+    test "0.00__00_01", 1E-6
+    test "0.0_01", 0.001
+    test "0.00_000_1", 1E-6
+    test "0.00000_1", 1E-6
+    test "1_0.00_0001", 10.000001
+    test "1__00.00_0001", 1_00.000001
+    test "inf", Inf
+    test "-inf", -Inf
+    test "-Inf", -Inf
+    test "-INF", -Inf
+    test "NaN", NaN
+    test "-nan", NaN
+    test ".1", 0.1
+    test "-.1", -0.1
+    test "-0", -0.0
+    test "-0", -0'f # see #18246, -0 won't work
+    test ".1e-1", 0.1e-1
+    test "0_1_2_3.0_1_2_3E+0_1_2", 123.0123e12
+    test "0_1_2.e-0", 12e0
+    test "0_1_2e-0", 12e0
+    test "-0e0", -0.0
+    test "-0e-0", -0.0
+
+  reject "a"
+  reject ""
+  reject "e1"
+  reject "infa"
+  reject "infe1"
+  reject "_"
+  reject "1e"
+
+  when false: # gray area; these numbers should probably be invalid
+    reject "1_"
+    reject "1_.0"
+    reject "1.0_"
+
+  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(nimPreviewFloatRoundtrip):
+        doAssert $a == "0.30000000000000004"
+      else:
+        whenRuntimeJs: discard
+        do: doAssert $a == "0.3"
+    block: # example 2
+      const a = 0.1+0.2
+      when defined(nimPreviewFloatRoundtrip):
+        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(nimPreviewFloatRoundtrip):
+        doAssert $[$a1, $a2] == """["0.30000000000000004", "0.30000000000000004"]"""
+      else:
+        whenRuntimeJs: discard
+        do: doAssert $[$a1, $a2] == """["0.3", "0.3"]"""
+
+  when defined(nimPreviewFloatRoundtrip):
+    block: # bug #18148
+      var a = 1.1'f32
+      doAssert $a == "1.1", $a # was failing
+
+    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:
+          doAssert x == 1.2345679'f32
+          doAssert $x == "1.2345679"
+
+static: main()
+main()
diff --git a/tests/float/tissue5821.nim b/tests/float/tissue5821.nim
new file mode 100644
index 000000000..c4f561f09
--- /dev/null
+++ b/tests/float/tissue5821.nim
@@ -0,0 +1,15 @@
+discard """
+output: "ok"
+"""
+
+proc main(): void =
+  let a: float32 = 47.11'f32
+  doAssert a == 47.11'f32
+
+  let b: float64 = 10.234402823e+38'f64
+  doAssert b != 10.123402823e+38'f64
+  doAssert b == 10.234402823e+38'f64
+
+  echo "ok"
+
+main()
diff --git a/tests/float/tlenientops.nim b/tests/float/tlenientops.nim
new file mode 100644
index 000000000..586580670
--- /dev/null
+++ b/tests/float/tlenientops.nim
@@ -0,0 +1,100 @@
+discard """
+  exitcode: 0
+  output: ""
+"""
+
+import lenientops
+
+proc `~=`[T](a, b: T): bool = abs(a - b) < 1e-7
+
+block: # math binary operators
+  let i = 1
+  let f = 2.0
+
+  doAssert i + f ~= 3
+  doAssert f + i ~= 3
+
+  doAssert i - f ~= -1
+  doAssert f - i ~= 1
+
+  doAssert i * f ~= 2
+  doAssert f * i ~= 2
+
+  doAssert i / f ~= 0.5
+  doAssert f / i ~= 2
+
+block: # comparison operators
+  doAssert 1.int < 2.float
+  doAssert 1.float < 2.int
+  doAssert 1.int <= 2.float
+  doAssert 1.float <= 2.int
+  doAssert 2.int >= 1.float
+  doAssert 2.float >= 1.int
+  doAssert 2.int > 1.float
+  doAssert 2.float > 1.int
+
+block: # all type combinations
+  let i = 1
+  let f = 2.0
+
+  doAssert i.int + f.float ~= 3
+  doAssert i.int + f.float32 ~= 3
+  doAssert i.int + f.float64 ~= 3
+  doAssert i.int8 + f.float ~= 3
+  doAssert i.int8 + f.float32 ~= 3
+  doAssert i.int8 + f.float64 ~= 3
+  doAssert i.int16 + f.float ~= 3
+  doAssert i.int16 + f.float32 ~= 3
+  doAssert i.int16 + f.float64 ~= 3
+  doAssert i.int32 + f.float ~= 3
+  doAssert i.int32 + f.float32 ~= 3
+  doAssert i.int32 + f.float64 ~= 3
+  doAssert i.int64 + f.float ~= 3
+  doAssert i.int64 + f.float32 ~= 3
+  doAssert i.int64 + f.float64 ~= 3
+  doAssert i.uint + f.float ~= 3
+  doAssert i.uint + f.float32 ~= 3
+  doAssert i.uint + f.float64 ~= 3
+  doAssert i.uint8 + f.float ~= 3
+  doAssert i.uint8 + f.float32 ~= 3
+  doAssert i.uint8 + f.float64 ~= 3
+  doAssert i.uint16 + f.float ~= 3
+  doAssert i.uint16 + f.float32 ~= 3
+  doAssert i.uint16 + f.float64 ~= 3
+  doAssert i.uint32 + f.float ~= 3
+  doAssert i.uint32 + f.float32 ~= 3
+  doAssert i.uint32 + f.float64 ~= 3
+  doAssert i.uint64 + f.float ~= 3
+  doAssert i.uint64 + f.float32 ~= 3
+  doAssert i.uint64 + f.float64 ~= 3
+
+  doAssert f.float + i.int  ~= 3
+  doAssert f.float32 + i.int ~= 3
+  doAssert f.float64 + i.int ~= 3
+  doAssert f.float + i.int8 ~= 3
+  doAssert f.float32 + i.int8 ~= 3
+  doAssert f.float64 + i.int8 ~= 3
+  doAssert f.float + i.int16 ~= 3
+  doAssert f.float32 + i.int16 ~= 3
+  doAssert f.float64 + i.int16 ~= 3
+  doAssert f.float + i.int32 ~= 3
+  doAssert f.float32 + i.int32 ~= 3
+  doAssert f.float64 + i.int32 ~= 3
+  doAssert f.float + i.int64 ~= 3
+  doAssert f.float32 + i.int64 ~= 3
+  doAssert f.float64 + i.int64 ~= 3
+  doAssert f.float + i.uint ~= 3
+  doAssert f.float32 + i.uint ~= 3
+  doAssert f.float64 + i.uint ~= 3
+  doAssert f.float + i.uint8 ~= 3
+  doAssert f.float32 + i.uint8 ~= 3
+  doAssert f.float64 + i.uint8 ~= 3
+  doAssert f.float + i.uint16 ~= 3
+  doAssert f.float32 + i.uint16 ~= 3
+  doAssert f.float64 + i.uint16 ~= 3
+  doAssert f.float + i.uint32 ~= 3
+  doAssert f.float32 + i.uint32 ~= 3
+  doAssert f.float64 + i.uint32 ~= 3
+  doAssert f.float + i.uint64 ~= 3
+  doAssert f.float32 + i.uint64 ~= 3
+  doAssert f.float64 + i.uint64 ~= 3