704_math.py 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. import math
  2. # ============================================================
  3. # Helper function for floating point comparison
  4. # ============================================================
  5. def isclose(a, b):
  6. return abs(a-b) < 0.000001
  7. # ============================================================
  8. # Constants: pi, e, inf, nan
  9. # ============================================================
  10. assert isclose(math.pi, 3.141592653589793)
  11. assert isclose(math.e, 2.718281828459045)
  12. assert math.isinf(math.inf)
  13. assert math.isnan(math.nan)
  14. # ============================================================
  15. # Rounding functions: ceil, floor, trunc, fabs
  16. # ============================================================
  17. # ceil - round up to nearest integer
  18. assert math.ceil(1.2) == 2
  19. assert math.ceil(-1.2) == -1
  20. assert math.ceil(2.0) == 2
  21. assert math.ceil(0) == 0
  22. # floor - round down to nearest integer
  23. assert math.floor(1.2) == 1
  24. assert math.floor(-1.2) == -2
  25. assert math.floor(2.0) == 2
  26. assert math.floor(0) == 0
  27. # trunc - truncate towards zero
  28. assert math.trunc(1.7) == 1
  29. assert math.trunc(-1.7) == -1
  30. assert math.trunc(2.0) == 2
  31. assert math.trunc(0) == 0
  32. # fabs - absolute value (returns float)
  33. assert isclose(math.fabs(-1.2), 1.2)
  34. assert isclose(math.fabs(1.2), 1.2)
  35. assert isclose(math.fabs(0), 0.0)
  36. assert isclose(math.fabs(-0.0), 0.0)
  37. # ============================================================
  38. # Classification functions: isnan, isinf, isfinite, isclose
  39. # ============================================================
  40. # isnan - check if value is NaN
  41. assert math.isnan(float('nan'))
  42. assert math.isnan(math.nan)
  43. assert not math.isnan(1.0)
  44. assert not math.isnan(math.inf)
  45. # isinf - check if value is infinity
  46. assert math.isinf(float('inf'))
  47. assert math.isinf(float('-inf'))
  48. assert math.isinf(math.inf)
  49. assert not math.isinf(1.0)
  50. assert not math.isinf(math.nan)
  51. # isfinite - check if value is finite (not inf or nan)
  52. assert math.isfinite(1.0)
  53. assert math.isfinite(0.0)
  54. assert math.isfinite(-1.0)
  55. assert not math.isfinite(math.inf)
  56. assert not math.isfinite(-math.inf)
  57. assert not math.isfinite(math.nan)
  58. # isclose - check if two values are close
  59. assert math.isclose(1.0, 1.0)
  60. assert math.isclose(1.0, 1.0 + 1e-10)
  61. assert not math.isclose(1.0, 1.1)
  62. # ============================================================
  63. # Power and logarithmic functions: exp, log, log2, log10, pow, sqrt
  64. # ============================================================
  65. # exp - e raised to the power x
  66. assert isclose(math.exp(0), 1.0)
  67. assert isclose(math.exp(1), math.e)
  68. assert isclose(math.exp(2), math.e * math.e)
  69. # log - natural logarithm (base e) or logarithm with custom base
  70. assert isclose(math.log(1), 0.0)
  71. assert isclose(math.log(math.e), 1.0)
  72. assert isclose(math.log(10), 2.302585092994046)
  73. assert isclose(math.log(100, 10), 2.0) # log base 10
  74. assert isclose(math.log(8, 2), 3.0) # log base 2
  75. # log2 - logarithm base 2
  76. assert isclose(math.log2(1), 0.0)
  77. assert isclose(math.log2(2), 1.0)
  78. assert isclose(math.log2(8), 3.0)
  79. assert isclose(math.log2(10), 3.321928094887362)
  80. # log10 - logarithm base 10
  81. assert isclose(math.log10(1), 0.0)
  82. assert isclose(math.log10(10), 1.0)
  83. assert isclose(math.log10(100), 2.0)
  84. assert isclose(math.log10(1000), 3.0)
  85. # pow - x raised to the power y
  86. assert isclose(math.pow(2, 3), 8.0)
  87. assert isclose(math.pow(2, 0), 1.0)
  88. assert isclose(math.pow(2, -1), 0.5)
  89. assert isclose(math.pow(4, 0.5), 2.0)
  90. assert isclose(math.pow(0, 0), 1.0)
  91. # sqrt - square root
  92. assert isclose(math.sqrt(4), 2.0)
  93. assert isclose(math.sqrt(2), 1.4142135623730951)
  94. assert isclose(math.sqrt(0), 0.0)
  95. assert isclose(math.sqrt(1), 1.0)
  96. # ============================================================
  97. # Trigonometric functions: sin, cos, tan, asin, acos, atan, atan2
  98. # ============================================================
  99. # sin - sine
  100. assert isclose(math.sin(0), 0.0)
  101. assert isclose(math.sin(math.pi / 2), 1.0)
  102. assert isclose(math.sin(math.pi), 0.0)
  103. assert isclose(math.sin(-math.pi / 2), -1.0)
  104. assert isclose(math.sin(-math.pi / 4), -0.7071067811865476)
  105. # cos - cosine
  106. assert isclose(math.cos(0), 1.0)
  107. assert isclose(math.cos(math.pi / 2), 0.0)
  108. assert isclose(math.cos(math.pi), -1.0)
  109. assert isclose(math.cos(-math.pi), -1.0)
  110. # tan - tangent
  111. assert isclose(math.tan(0), 0.0)
  112. assert isclose(math.tan(math.pi / 4), 1.0)
  113. assert isclose(math.tan(-math.pi / 4), -1.0)
  114. # asin - arc sine (inverse sine)
  115. assert isclose(math.asin(0), 0.0)
  116. assert isclose(math.asin(1), math.pi / 2)
  117. assert isclose(math.asin(-1), -math.pi / 2)
  118. assert isclose(math.asin(0.5), math.pi / 6)
  119. # acos - arc cosine (inverse cosine)
  120. assert isclose(math.acos(1), 0.0)
  121. assert isclose(math.acos(0), math.pi / 2)
  122. assert isclose(math.acos(-1), math.pi)
  123. assert isclose(math.acos(0.5), math.pi / 3)
  124. # atan - arc tangent (inverse tangent)
  125. assert isclose(math.atan(0), 0.0)
  126. assert isclose(math.atan(1), math.pi / 4)
  127. assert isclose(math.atan(-1), -math.pi / 4)
  128. # atan2 - arc tangent of y/x (handles quadrants correctly)
  129. assert isclose(math.atan2(0, 1), 0.0)
  130. assert isclose(math.atan2(1, 0), math.pi / 2)
  131. assert isclose(math.atan2(0, -1), math.pi)
  132. assert isclose(math.atan2(-1, 0), -math.pi / 2)
  133. assert isclose(math.atan2(1, 1), math.pi / 4)
  134. assert isclose(math.atan2(-1, -1), -3 * math.pi / 4)
  135. # ============================================================
  136. # Angle conversion functions: degrees, radians
  137. # ============================================================
  138. # degrees - convert radians to degrees
  139. assert isclose(math.degrees(0), 0.0)
  140. assert isclose(math.degrees(math.pi), 180.0)
  141. assert isclose(math.degrees(math.pi / 2), 90.0)
  142. assert isclose(math.degrees(2 * math.pi), 360.0)
  143. # radians - convert degrees to radians
  144. assert isclose(math.radians(0), 0.0)
  145. assert isclose(math.radians(180), math.pi)
  146. assert isclose(math.radians(90), math.pi / 2)
  147. assert isclose(math.radians(360), 2 * math.pi)
  148. # ============================================================
  149. # Arithmetic functions: fmod, modf, copysign, fsum, gcd, factorial
  150. # ============================================================
  151. # fmod - floating point modulo
  152. assert isclose(math.fmod(5.0, 3.0), 2.0)
  153. assert isclose(math.fmod(-5.0, 3.0), -2.0)
  154. assert isclose(math.fmod(5.0, -3.0), 2.0)
  155. assert isclose(math.fmod(-5.0, -3.0), -2.0)
  156. assert isclose(math.fmod(4.0, 3.0), 1.0)
  157. assert isclose(math.fmod(-4.0, 3.0), -1.0)
  158. assert isclose(math.fmod(-2.0, 3.0), -2.0)
  159. assert isclose(math.fmod(2.0, 3.0), 2.0)
  160. # modf - split into fractional and integer parts
  161. frac, integer = math.modf(1.5)
  162. assert isclose(frac, 0.5)
  163. assert isclose(integer, 1.0)
  164. frac, integer = math.modf(-1.5)
  165. assert isclose(frac, -0.5)
  166. assert isclose(integer, -1.0)
  167. frac, integer = math.modf(2.0)
  168. assert isclose(frac, 0.0)
  169. assert isclose(integer, 2.0)
  170. frac, integer = math.modf(0.0)
  171. assert isclose(frac, 0.0)
  172. assert isclose(integer, 0.0)
  173. # copysign - return x with the sign of y
  174. assert isclose(math.copysign(1.0, -1.0), -1.0)
  175. assert isclose(math.copysign(-1.0, 1.0), 1.0)
  176. assert isclose(math.copysign(1.0, 1.0), 1.0)
  177. assert isclose(math.copysign(-1.0, -1.0), -1.0)
  178. assert isclose(math.copysign(5.0, -0.0), -5.0)
  179. assert isclose(math.copysign(0.0, -1.0), 0.0) # sign of zero may vary
  180. # fsum - accurate floating point sum
  181. assert math.fsum([0.1] * 10) == 1.0
  182. assert math.fsum([]) == 0.0
  183. assert math.fsum([1.0, 2.0, 3.0]) == 6.0
  184. assert math.fsum([0.1, 0.2, 0.3]) == 0.6
  185. # gcd - greatest common divisor
  186. assert math.gcd(10, 5) == 5
  187. assert math.gcd(10, 6) == 2
  188. assert math.gcd(10, 7) == 1
  189. assert math.gcd(10, 10) == 10
  190. assert math.gcd(-10, 10) == 10
  191. assert math.gcd(10, -10) == 10
  192. assert math.gcd(-10, -10) == 10
  193. assert math.gcd(0, 5) == 5
  194. assert math.gcd(5, 0) == 5
  195. assert math.gcd(0, 0) == 0
  196. # factorial - n!
  197. assert math.factorial(0) == 1
  198. assert math.factorial(1) == 1
  199. assert math.factorial(2) == 2
  200. assert math.factorial(3) == 6
  201. assert math.factorial(4) == 24
  202. assert math.factorial(5) == 120
  203. assert math.factorial(10) == 3628800
  204. # ============================================================
  205. # Special value tests
  206. # ============================================================
  207. # Test NaN generation from invalid operations
  208. a = -0.1
  209. a = a ** a
  210. assert math.isnan(a)
  211. assert not math.isinf(a)
  212. # Test infinity
  213. assert math.isinf(float("inf"))
  214. assert math.isinf(float("-inf"))
  215. assert not math.isnan(float("inf"))