tfloats.nim 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. discard """
  2. matrix: "-d:nimPreviewFloatRoundtrip; -u:nimPreviewFloatRoundtrip"
  3. targets: "c cpp js"
  4. """
  5. #[
  6. xxx merge all or most float tests into this file
  7. ]#
  8. import std/[fenv, math, strutils]
  9. import stdtest/testutils
  10. proc equalsOrNaNs(a, b: float): bool =
  11. if isNaN(a): isNaN(b)
  12. elif a == 0:
  13. b == 0 and signbit(a) == signbit(b)
  14. else:
  15. a == b
  16. template reject(a) =
  17. doAssertRaises(ValueError): discard parseFloat(a)
  18. template main =
  19. block:
  20. proc test(a: string, b: float) =
  21. let a2 = a.parseFloat
  22. doAssert equalsOrNaNs(a2, b), $(a, a2, b)
  23. test "0.00_0001", 1E-6
  24. test "0.00__00_01", 1E-6
  25. test "0.0_01", 0.001
  26. test "0.00_000_1", 1E-6
  27. test "0.00000_1", 1E-6
  28. test "1_0.00_0001", 10.000001
  29. test "1__00.00_0001", 1_00.000001
  30. test "inf", Inf
  31. test "-inf", -Inf
  32. test "-Inf", -Inf
  33. test "-INF", -Inf
  34. test "NaN", NaN
  35. test "-nan", NaN
  36. test ".1", 0.1
  37. test "-.1", -0.1
  38. test "-0", -0.0
  39. test "-0", -0'f # see #18246, -0 won't work
  40. test ".1e-1", 0.1e-1
  41. test "0_1_2_3.0_1_2_3E+0_1_2", 123.0123e12
  42. test "0_1_2.e-0", 12e0
  43. test "0_1_2e-0", 12e0
  44. test "-0e0", -0.0
  45. test "-0e-0", -0.0
  46. reject "a"
  47. reject ""
  48. reject "e1"
  49. reject "infa"
  50. reject "infe1"
  51. reject "_"
  52. reject "1e"
  53. when false: # gray area; these numbers should probably be invalid
  54. reject "1_"
  55. reject "1_.0"
  56. reject "1.0_"
  57. block: # bugs mentioned in https://github.com/nim-lang/Nim/pull/18504#issuecomment-881635317
  58. block: # example 1
  59. let a = 0.1+0.2
  60. doAssert a != 0.3
  61. when defined(nimPreviewFloatRoundtrip):
  62. doAssert $a == "0.30000000000000004"
  63. else:
  64. whenRuntimeJs: discard
  65. do: doAssert $a == "0.3"
  66. block: # example 2
  67. const a = 0.1+0.2
  68. when defined(nimPreviewFloatRoundtrip):
  69. doAssert $($a, a) == """("0.30000000000000004", 0.30000000000000004)"""
  70. else:
  71. whenRuntimeJs: discard
  72. do: doAssert $($a, a) == """("0.3", 0.3)"""
  73. block: # example 3
  74. const a1 = 0.1+0.2
  75. let a2 = a1
  76. doAssert a1 != 0.3
  77. when defined(nimPreviewFloatRoundtrip):
  78. doAssert $[$a1, $a2] == """["0.30000000000000004", "0.30000000000000004"]"""
  79. else:
  80. whenRuntimeJs: discard
  81. do: doAssert $[$a1, $a2] == """["0.3", "0.3"]"""
  82. when defined(nimPreviewFloatRoundtrip):
  83. block: # bug #18148
  84. var a = 1.1'f32
  85. doAssert $a == "1.1", $a # was failing
  86. block: # bug #18400
  87. block:
  88. let a1 = 0.1'f32
  89. let a2 = 0.2'f32
  90. let a3 = a1 + a2
  91. var s = ""
  92. s.addFloat(a3)
  93. whenVMorJs: discard # xxx refs #12884
  94. do:
  95. doAssert a3 == 0.3'f32
  96. doAssert $a3 == "0.3"
  97. block:
  98. let a1 = 0.1
  99. let a2 = 0.2
  100. let a3 = a1 + a2
  101. var s = ""
  102. s.addFloat(a3)
  103. doAssert a3 != 0.3
  104. doAssert $a3 == "0.30000000000000004"
  105. block:
  106. var s = [-13.888888'f32]
  107. whenRuntimeJs: discard
  108. do:
  109. doAssert $s == "[-13.888888]"
  110. doAssert $s[0] == "-13.888888"
  111. block: # bug #7717
  112. proc test(f: float) =
  113. let f2 = $f
  114. let f3 = parseFloat(f2)
  115. doAssert equalsOrNaNs(f, f3), $(f, f2, f3)
  116. test 1.0 + epsilon(float64)
  117. test 1000000.0000000123
  118. test log2(100000.0)
  119. test maximumPositiveValue(float32)
  120. test maximumPositiveValue(float64)
  121. test minimumPositiveValue(float32)
  122. test minimumPositiveValue(float64)
  123. block: # bug #12884
  124. block: # example 1
  125. const x0: float32 = 1.32
  126. let x1 = 1.32
  127. let x2 = 1.32'f32
  128. var x3: float32 = 1.32
  129. doAssert $(x0, x1, x2, x3) == "(1.32, 1.32, 1.32, 1.32)"
  130. block: # example https://github.com/nim-lang/Nim/issues/12884#issuecomment-564967962
  131. let x = float(1.32'f32)
  132. when nimvm: discard # xxx prints 1.3
  133. else:
  134. when not defined(js):
  135. doAssert $x == "1.3200000524520874"
  136. doAssert $1.32 == "1.32"
  137. doAssert $1.32'f32 == "1.32"
  138. let x2 = 1.32'f32
  139. doAssert $x2 == "1.32"
  140. block:
  141. var x = 1.23456789012345'f32
  142. when nimvm:
  143. discard # xxx, refs #12884
  144. else:
  145. doAssert x == 1.2345679'f32
  146. doAssert $x == "1.2345679"
  147. static: main()
  148. main()