930_deterministic_float.py 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. import math
  2. import pkpy
  3. config = pkpy.configmacros
  4. if config["PK_ENABLE_DETERMINISM"] == 0:
  5. exit(0)
  6. def assertEqual(a, b):
  7. if a == b:
  8. return
  9. print(f'{a} != {b} ({a-b})')
  10. raise AssertionError
  11. # test constants
  12. assertEqual(math.pi, 3.14159265358979323846)
  13. assertEqual(math.e, 2.7182818284590452354)
  14. assert math.inf, math.inf
  15. assert math.nan != math.nan
  16. # test ceil
  17. assert math.ceil(math.pi) == 4
  18. assert math.ceil(-math.e) == -2
  19. # test floor
  20. assert math.floor(math.pi) == 3
  21. assert math.floor(-math.e) == -3
  22. # test trunc
  23. assert math.trunc(-math.e) == -2
  24. assert math.trunc(3.999) == 3
  25. # test fabs
  26. assertEqual(math.fabs(math.pi), 3.14159265358979323846)
  27. assertEqual(math.fabs(-math.pi), 3.14159265358979323846)
  28. # test gcd
  29. assertEqual(math.gcd(10, 5), 5)
  30. assertEqual(math.gcd(10, 6), 2)
  31. assertEqual(math.gcd(10, 7), 1)
  32. assertEqual(math.gcd(10, 10), 10)
  33. assertEqual(math.gcd(-10, 10), 10)
  34. # test isfinite, isinf, isnan
  35. assertEqual(math.isfinite(math.pi), True)
  36. assertEqual(math.isfinite(math.inf), False)
  37. assertEqual(math.isfinite(math.nan), False)
  38. assertEqual(math.isinf(math.pi), False)
  39. assertEqual(math.isinf(math.inf), True)
  40. assertEqual(math.isinf(math.nan), False)
  41. assertEqual(math.isnan(math.pi), False)
  42. assertEqual(math.isnan(math.inf), False)
  43. assertEqual(math.isnan(math.nan), True)
  44. # test exp
  45. assertEqual(math.exp(0), 1.0)
  46. assertEqual(math.exp(1), math.e)
  47. assertEqual(math.exp(1.5), 4.48168907033806362960604019463)
  48. assertEqual(math.exp(3), 20.0855369231876608182574273087)
  49. assertEqual(math.exp(-3), 0.04978706836786396527916309651)
  50. assertEqual(math.exp(-2.253647), 0.1050155336754953 - 1.387778780781446e-17)
  51. assertEqual(math.exp(4.729036), 113.186398052200445363268954679)
  52. # test log series
  53. assertEqual(math.log(0), -math.inf)
  54. assertEqual(math.log(1), 0.0)
  55. assertEqual(math.log(2), 0.69314718055994530942)
  56. assertEqual(math.log(math.e), 1.0)
  57. assertEqual(math.log(10), 2.30258509299404545700440394284)
  58. assertEqual(math.log(28.897124), 3.363742074595449)
  59. assertEqual(math.log2(math.e), 1.4426950408889634074)
  60. assertEqual(math.log2(78.781291), 6.299781153677818)
  61. assertEqual(math.log10(math.e), 0.43429448190325182765)
  62. assertEqual(math.log10(56.907822), 1.755171964426069 + 4.440892098500626e-16)
  63. # test pow
  64. assertEqual(math.pow(2,2), 4.0)
  65. assertEqual(math.pow(1.41421356237309504880, 2), 2.0 + 4.440892098500626e-16)
  66. assertEqual(math.pow(0.70710678118654752440, 2), 0.5000000000000001)
  67. assertEqual(math.pow(-1.255782,-3), -0.5049603042167915)
  68. assertEqual(math.pow(6.127042, 4.071529), 1604.40754645674428502388764172)
  69. # test sqrt
  70. # these match CPython bit-for-bit (hardware sqrt is correctly rounded, see dmath_sqrt)
  71. assertEqual(math.sqrt(2), 1.4142135623730951)
  72. assertEqual(math.sqrt(math.pi), 1.7724538509055159)
  73. assertEqual(math.sqrt(125.872509), 11.21929182257062)
  74. assertEqual(math.sqrt(1225.296280), 35.00423231553579)
  75. assertEqual(math.sqrt(0.1), 0.31622776601683794)
  76. assertEqual(math.sqrt(1e300), 1e150)
  77. assertEqual(math.sqrt(1.7976931348623157e308), 1.3407807929942596e154)
  78. # subnormal inputs
  79. assertEqual(math.sqrt(1e-320), 9.99994433575849e-161)
  80. assertEqual(math.sqrt(5e-324), 2.2227587494850775e-162)
  81. # perfect squares must be exact, the old exp/log based sqrt gave sqrt(9) == 2.9999999999999996
  82. for i in range(2000):
  83. assertEqual(math.sqrt(i * i), float(i))
  84. # special values
  85. assertEqual(math.sqrt(math.inf), math.inf)
  86. assertEqual(math.copysign(1.0, math.sqrt(0.0)), 1.0)
  87. assertEqual(math.copysign(1.0, math.sqrt(-0.0)), -1.0)
  88. assert math.isnan(math.sqrt(-1))
  89. assert math.isnan(math.sqrt(-math.inf))
  90. assert math.isnan(math.sqrt(math.nan))
  91. # test cos, sin, tan
  92. assertEqual(math.cos(0), 1.0)
  93. assertEqual(math.cos(math.pi/2), 6.123233995736766e-17)
  94. assertEqual(math.cos(math.pi), -1.0)
  95. assertEqual(math.cos(-11.352808), 0.3496839289707818 - 5.551115123125783e-17)
  96. assertEqual(math.cos(7.294708), 0.530570640518482)
  97. assertEqual(math.sin(0), 0.0)
  98. assertEqual(math.sin(math.pi/2), 1.0)
  99. assertEqual(math.sin(math.pi), 1.224646799147353e-16 + 2.465190328815662e-32)
  100. assertEqual(math.sin(-2.837592), -0.2993398018896187)
  101. assertEqual(math.sin(9.294782), 0.1296301374714747)
  102. assertEqual(math.tan(0), 0.0)
  103. assertEqual(math.tan(math.pi/2), 1.633123935319537e+16)
  104. assertEqual(math.tan(math.pi), -1.224646799147353e-16 - 2.465190328815662e-32)
  105. assertEqual(math.tan(-4.812975), 9.908188146466314)
  106. assertEqual(math.tan(1.875814), -3.176189742032396 - 4.440892098500626e-16)
  107. # test acos, asin, atan
  108. # these match CPython bit-for-bit (ported from Zig, see src/common/dmath_zig.c)
  109. assertEqual(math.acos(0), 1.5707963267948966)
  110. assertEqual(math.acos(1), 0.0)
  111. assertEqual(math.acos(-0.758293), 2.4314869951218965)
  112. assertEqual(math.acos(0.024758), 1.546035796825635)
  113. assertEqual(math.asin(0), 0.0)
  114. assertEqual(math.asin(1), 1.5707963267948966)
  115. assertEqual(math.asin(-0.225895), -0.22786168657739128)
  116. assertEqual(math.asin(0.955658), 1.2718861958194234)
  117. assertEqual(math.atan(0), 0.0)
  118. assertEqual(math.atan(1), 0.7853981633974483)
  119. assertEqual(math.atan(-3.758927), -1.3107852846106174)
  120. assertEqual(math.atan(35.789293), 1.542862277280122)
  121. # test atan2
  122. assertEqual(math.atan2(math.pi/4, math.pi/4), 0.7853981633974483)
  123. assertEqual(math.atan2(-math.pi/4, math.pi/4), -0.7853981633974483)
  124. assertEqual(math.atan2(-math.pi/4, -math.pi/4), -2.356194490192345)
  125. assertEqual(math.atan2(math.pi/4, -math.pi/4), 2.356194490192345)
  126. assertEqual(math.atan2(1.573823, 0.685329), 1.160103682924653)
  127. assertEqual(math.atan2(-0.899663, 0.668972), -0.9314162757114095)
  128. assertEqual(math.atan2(-0.762894, -0.126497), -1.7351133471732965)
  129. assertEqual(math.atan2(0.468463, -0.992734), 2.7006834106923736)
  130. # near-vertical vectors used to hit a NaN in the old atan (ratio >= 2^26),
  131. # which silently turned into direction index 0 for callers
  132. assertEqual(math.atan2(1.0, 1e-8), 1.5707963167948966)
  133. assertEqual(math.atan2(1.0, 1e-12), 1.5707963267938967)
  134. assertEqual(math.atan2(-3.5, 1e-15), -1.5707963267948963)
  135. # test fsum, sum
  136. fsum_sin = math.fsum([math.sin(i) for i in range(5000)])
  137. fsum_cos = math.fsum([math.cos(i) for i in range(5000, 9999)])
  138. assertEqual(fsum_sin, 1.267667771014267 + 2.220446049250313e-16)
  139. assertEqual(fsum_cos, 1.949547793618193 - 4.440892098500626e-16)
  140. assertEqual(fsum_sin + fsum_cos, 3.21721556463246)
  141. sum_sin = sum([math.sin(i) for i in range(5000)])
  142. sum_cos = sum([math.cos(i) for i in range(5000, 9999)])
  143. assertEqual(sum_sin, 1.267667771014264 - 2.220446049250313e-16)
  144. assertEqual(sum_cos, 1.949547793618197 - 4.440892098500626e-16)
  145. assertEqual(sum_sin + sum_cos, 3.21721556463246 + 4.440892098500626e-16)
  146. # test fmod
  147. assertEqual(math.fmod(-2.0, 3.0), -2.0)
  148. assertEqual(math.fmod(2.0, 3.0), 2.0)
  149. assertEqual(math.fmod(4.0, 3.0), 1.0)
  150. assertEqual(math.fmod(-4.0, 3.0), -1.0)
  151. # test modf
  152. x, y = math.modf(math.pi)
  153. assertEqual(x, 0.14159265358979323846 - 1.110223024625157e-16)
  154. assertEqual(y, 3.0)
  155. x, y = math.modf(-math.e)
  156. assertEqual(x, -0.7182818284590451)
  157. assertEqual(y, -2.0)
  158. # test factorial
  159. assertEqual(math.factorial(0), 1)
  160. assertEqual(math.factorial(1), 1)
  161. assertEqual(math.factorial(2), 2)
  162. assertEqual(math.factorial(3), 6)
  163. assertEqual(math.factorial(4), 24)
  164. assertEqual(math.factorial(5), 120)