tfloats.nim 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  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. when false: # pending bug #18246
  40. test "-0", -0.0
  41. test ".1e-1", 0.1e-1
  42. test "0_1_2_3.0_1_2_3E+0_1_2", 123.0123e12
  43. test "0_1_2.e-0", 12e0
  44. test "0_1_2e-0", 12e0
  45. test "-0e0", -0.0
  46. test "-0e-0", -0.0
  47. reject "a"
  48. reject ""
  49. reject "e1"
  50. reject "infa"
  51. reject "infe1"
  52. reject "_"
  53. reject "1e"
  54. when false: # gray area; these numbers should probably be invalid
  55. reject "1_"
  56. reject "1_.0"
  57. reject "1.0_"
  58. block: # bugs mentioned in https://github.com/nim-lang/Nim/pull/18504#issuecomment-881635317
  59. block: # example 1
  60. let a = 0.1+0.2
  61. doAssert a != 0.3
  62. when defined(nimPreviewFloatRoundtrip):
  63. doAssert $a == "0.30000000000000004"
  64. else:
  65. whenRuntimeJs: discard
  66. do: doAssert $a == "0.3"
  67. block: # example 2
  68. const a = 0.1+0.2
  69. when defined(nimPreviewFloatRoundtrip):
  70. doAssert $($a, a) == """("0.30000000000000004", 0.30000000000000004)"""
  71. else:
  72. whenRuntimeJs: discard
  73. do: doAssert $($a, a) == """("0.3", 0.3)"""
  74. block: # example 3
  75. const a1 = 0.1+0.2
  76. let a2 = a1
  77. doAssert a1 != 0.3
  78. when defined(nimPreviewFloatRoundtrip):
  79. doAssert $[$a1, $a2] == """["0.30000000000000004", "0.30000000000000004"]"""
  80. else:
  81. whenRuntimeJs: discard
  82. do: doAssert $[$a1, $a2] == """["0.3", "0.3"]"""
  83. when defined(nimPreviewFloatRoundtrip):
  84. block: # bug #18148
  85. var a = 1.1'f32
  86. doAssert $a == "1.1", $a # was failing
  87. block: # bug #18400
  88. block:
  89. let a1 = 0.1'f32
  90. let a2 = 0.2'f32
  91. let a3 = a1 + a2
  92. var s = ""
  93. s.addFloat(a3)
  94. whenVMorJs: discard # xxx refs #12884
  95. do:
  96. doAssert a3 == 0.3'f32
  97. doAssert $a3 == "0.3"
  98. block:
  99. let a1 = 0.1
  100. let a2 = 0.2
  101. let a3 = a1 + a2
  102. var s = ""
  103. s.addFloat(a3)
  104. doAssert a3 != 0.3
  105. doAssert $a3 == "0.30000000000000004"
  106. block:
  107. var s = [-13.888888'f32]
  108. whenRuntimeJs: discard
  109. do:
  110. doAssert $s == "[-13.888888]"
  111. doAssert $s[0] == "-13.888888"
  112. block: # bug #7717
  113. proc test(f: float) =
  114. let f2 = $f
  115. let f3 = parseFloat(f2)
  116. doAssert equalsOrNaNs(f, f3), $(f, f2, f3)
  117. test 1.0 + epsilon(float64)
  118. test 1000000.0000000123
  119. test log2(100000.0)
  120. test maximumPositiveValue(float32)
  121. test maximumPositiveValue(float64)
  122. test minimumPositiveValue(float32)
  123. test minimumPositiveValue(float64)
  124. block: # bug #12884
  125. block: # example 1
  126. const x0: float32 = 1.32
  127. let x1 = 1.32
  128. let x2 = 1.32'f32
  129. var x3: float32 = 1.32
  130. doAssert $(x0, x1, x2, x3) == "(1.32, 1.32, 1.32, 1.32)"
  131. block: # example https://github.com/nim-lang/Nim/issues/12884#issuecomment-564967962
  132. let x = float(1.32'f32)
  133. when nimvm: discard # xxx prints 1.3
  134. else:
  135. when not defined(js):
  136. doAssert $x == "1.3200000524520874"
  137. doAssert $1.32 == "1.32"
  138. doAssert $1.32'f32 == "1.32"
  139. let x2 = 1.32'f32
  140. doAssert $x2 == "1.32"
  141. block:
  142. var x = 1.23456789012345'f32
  143. when nimvm:
  144. discard # xxx, refs #12884
  145. else:
  146. when not defined(js):
  147. doAssert x == 1.2345679'f32
  148. doAssert $x == "1.2345679"
  149. static: main()
  150. main()