test-numeric.scm 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. ;;; Copyright (C) 2023 Robin Templeton
  2. ;;;
  3. ;;; Licensed under the Apache License, Version 2.0 (the "License");
  4. ;;; you may not use this file except in compliance with the License.
  5. ;;; You may obtain a copy of the License at
  6. ;;;
  7. ;;; http://www.apache.org/licenses/LICENSE-2.0
  8. ;;;
  9. ;;; Unless required by applicable law or agreed to in writing, software
  10. ;;; distributed under the License is distributed on an "AS IS" BASIS,
  11. ;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. ;;; See the License for the specific language governing permissions and
  13. ;;; limitations under the License.
  14. ;;; Commentary:
  15. ;;;
  16. ;;; Miscellaneous numeric tower tests, primarily for mixed-type
  17. ;;; operations.
  18. ;;;
  19. ;;; Code:
  20. (use-modules (ice-9 format)
  21. (srfi srfi-64)
  22. (test utils))
  23. (test-begin "test-numeric")
  24. ;; TODO: Reenable commented-out tests, most of which are failing due to
  25. ;; exactness conversion not working properly
  26. ;; Flonum<->fraction comparison
  27. ;; ...with infinities and NaN
  28. (test-call "#t" (lambda (a b) (< a b)) 1/2 +inf.0)
  29. (test-call "#f" (lambda (a b) (< a b)) 1/2 -inf.0)
  30. (test-call "#f" (lambda (a b) (< a b)) +nan.0 1/2)
  31. (test-call "#f" (lambda (a b) (< a b)) +inf.0 1/2)
  32. (test-call "#t" (lambda (a b) (< a b)) -inf.0 1/2)
  33. (test-call "#f" (lambda (a b) (< a b)) 1/2 +nan.0)
  34. (test-call "#t" (lambda (a b) (<= a b)) 1/2 +inf.0)
  35. (test-call "#f" (lambda (a b) (<= a b)) 1/2 -inf.0)
  36. (test-call "#f" (lambda (a b) (<= a b)) +nan.0 1/2)
  37. (test-call "#f" (lambda (a b) (<= a b)) +inf.0 1/2)
  38. (test-call "#t" (lambda (a b) (<= a b)) -inf.0 1/2)
  39. (test-call "#f" (lambda (a b) (<= a b)) 1/2 +nan.0)
  40. (test-call "#f" (lambda (a b) (= a b)) 1/2 +inf.0)
  41. (test-call "#f" (lambda (a b) (= a b)) 1/2 -inf.0)
  42. (test-call "#f" (lambda (a b) (= a b)) +nan.0 1/2)
  43. (test-call "#f" (lambda (a b) (= a b)) +inf.0 1/2)
  44. (test-call "#f" (lambda (a b) (= a b)) -inf.0 1/2)
  45. (test-call "#f" (lambda (a b) (= a b)) 1/2 +nan.0)
  46. ;; ...with ordinary flonums
  47. (test-call "#t" (lambda (a b) (< a b)) 1/2 1.0)
  48. (test-call "#f" (lambda (a b) (< a b)) 1/2 -1.0)
  49. (test-call "#f" (lambda (a b) (< a b)) 1.0 1/2)
  50. (test-call "#t" (lambda (a b) (< a b)) -1.0 1/2)
  51. (test-call "#t" (lambda (a b) (<= a b)) 1/2 1.0)
  52. (test-call "#f" (lambda (a b) (<= a b)) 1/2 -1.0)
  53. (test-call "#f" (lambda (a b) (<= a b)) 1.0 1/2)
  54. (test-call "#t" (lambda (a b) (<= a b)) -1.0 1/2)
  55. (test-call "#f" (lambda (a b) (= a b)) 1/2 1.0)
  56. (test-call "#f" (lambda (a b) (= a b)) 1/2 -1.0)
  57. (test-call "#f" (lambda (a b) (= a b)) 1.0 1/2)
  58. (test-call "#f" (lambda (a b) (= a b)) -1.0 1/2)
  59. (test-call "#t" (lambda (a b) (= a b)) 1/2 0.5)
  60. (test-call "#t" (lambda (a b) (= a b)) 0.5 1/2)
  61. (test-call "#t" (lambda (a b) (<= a b)) 1/2 0.5)
  62. (test-call "#t" (lambda (a b) (<= a b)) 0.5 1/2)
  63. (test-call "#t" (lambda (a b) (= a b)) 0.5 1/2)
  64. (test-call "#t" (lambda (a b) (= a b)) 0.5 1/2)
  65. ;; exact
  66. (test-call "1" (lambda (a) (exact a)) 1)
  67. (test-call "1/2" (lambda (a) (exact a)) 1/2)
  68. (test-call "0" (lambda (a) (exact a)) 0.0)
  69. (test-call "0" (lambda (a) (exact a)) -0.0)
  70. (test-call "1/2" (lambda (a) (exact a)) 0.5)
  71. (test-call "-1/2" (lambda (a) (exact a)) -0.5)
  72. (test-call "9999" (lambda (a) (exact a)) 9999.0)
  73. (test-call "-9999" (lambda (a) (exact a)) -9999.0)
  74. ;; subnormal conversion
  75. (test-call (format #f "~d/~d" #xcccccccccccd (ash 2 1072))
  76. (lambda (a) (exact a))
  77. 2.2250738585072014e-309)
  78. ;; numeric equivalence
  79. (test-call "#t" (lambda (a b) (eqv? a b)) 1 1)
  80. (test-call "#f" (lambda (a b) (eqv? a b)) 1 1.0)
  81. (test-call "#t" (lambda (a b) (eqv? a (+ b b))) 1/2 1/4)
  82. (test-call "#t" (lambda (a b) (eqv? a b)) +nan.0 +nan.0)
  83. (test-call "#t" (lambda (a b) (eqv? a b)) +inf.0 +inf.0)
  84. (test-call "#t" (lambda (a b) (eqv? a b)) -inf.0 -inf.0)
  85. (test-call "#t" (lambda (a b) (equal? a b)) 1 1)
  86. (test-call "#f" (lambda (a b) (equal? a b)) 1 1.0)
  87. (test-call "#t" (lambda (a b) (equal? a (+ b b))) 1/2 1/4)
  88. (test-call "#t" (lambda (a b) (equal? a b)) +nan.0 +nan.0)
  89. (test-call "#t" (lambda (a b) (equal? a b)) +inf.0 +inf.0)
  90. (test-call "#t" (lambda (a b) (equal? a b)) -inf.0 -inf.0)
  91. ;; numerator and denominator
  92. (test-call "42" (lambda (a) (numerator a)) 42)
  93. (test-call "1" (lambda (a) (denominator a)) 42)
  94. (test-call "3" (lambda (a) (numerator a)) 6/4)
  95. (test-call "2" (lambda (a) (denominator a)) 6/4)
  96. (test-call "3.0" (lambda (a) (numerator (inexact a))) 6/4)
  97. (test-call "2.0" (lambda (a) (denominator (inexact a))) 6/4)
  98. ;; log and exp
  99. (test-call "0.0" (lambda (a) (log a)) 1)
  100. (test-call "2.0" (lambda (a b) (log a b)) 100 10)
  101. (test-call "1.0" (lambda (a) (exp (log a))) 1)
  102. (test-call "0.5" (lambda (a) (exp (log a))) 1/2)
  103. ;; expt
  104. (test-call "1" (lambda (a b) (expt a b)) 0 0)
  105. (test-call "1.0" (lambda (a b) (expt a b)) 0 0.0)
  106. (test-call "0" (lambda (a b) (expt a b)) 0 42)
  107. (test-call "0.0" (lambda (a b) (expt a b)) 0 42.0)
  108. (test-call "+nan.0" (lambda (a b) (expt a b)) 0 -1)
  109. (test-call "1.0" (lambda (a b) (expt a b)) 0.0 0)
  110. (test-call "1.0" (lambda (a b) (expt a b)) 0.0 0.0)
  111. (test-call "0.0" (lambda (a b) (expt a b)) 0.0 42)
  112. (test-call "0.0" (lambda (a b) (expt a b)) 0.0 42.0)
  113. (test-call "+nan.0" (lambda (a b) (expt a b)) 0.0 -1)
  114. (test-call "1" (lambda (a b) (expt a b)) 1 0)
  115. (test-call "1" (lambda (a b) (expt a b)) 1 1)
  116. (test-call "1" (lambda (a b) (expt a b)) 1 2)
  117. (test-call "1" (lambda (a b) (expt a b)) 1 3)
  118. (test-call "1" (lambda (a b) (expt a b)) 2 0)
  119. (test-call "2" (lambda (a b) (expt a b)) 2 1)
  120. (test-call "4" (lambda (a b) (expt a b)) 2 2)
  121. (test-call "8" (lambda (a b) (expt a b)) 2 3)
  122. (test-call "1" (lambda (a b) (expt a b)) 1/2 0)
  123. (test-call "1/2" (lambda (a b) (expt a b)) 1/2 1)
  124. (test-call "1/4" (lambda (a b) (expt a b)) 1/2 2)
  125. (test-call "1/8" (lambda (a b) (expt a b)) 1/2 3)
  126. (test-call "2.0" (lambda (a b) (expt a b)) 4 1/2)
  127. (test-call "2.0" (lambda (a b) (expt a b)) 4 0.5)
  128. (test-call "2.0" (lambda (a b) (expt a b)) 4.0 1/2)
  129. (test-call "2.0" (lambda (a b) (expt a b)) 4.0 0.5)
  130. (test-call "+inf.0" (lambda (a b) (expt a b)) +inf.0 +inf.0)
  131. (test-call "0.0" (lambda (a b) (expt a b)) +inf.0 -inf.0)
  132. ;; quotient, remainder and modulus with a flonum argument
  133. (test-call "12.0" (lambda (a b) (quotient a b)) 123.0 10.0)
  134. (test-call "12.0" (lambda (a b) (quotient a b)) 123.0 10)
  135. (test-call "12.0" (lambda (a b) (quotient a b)) 123 10.0)
  136. (test-call "53687091.0" (lambda (a b) (quotient a b)) 536870912.0 10.0)
  137. (test-call "53687091.0" (lambda (a b) (quotient a b)) 536870912.0 10)
  138. (test-call "53687091.0" (lambda (a b) (quotient a b)) 536870912 10.0)
  139. (test-call "3.0" (lambda (a b) (remainder a b)) 123.0 10.0)
  140. (test-call "3.0" (lambda (a b) (remainder a b)) 123.0 10)
  141. (test-call "3.0" (lambda (a b) (remainder a b)) 123 10.0)
  142. (test-call "2.0" (lambda (a b) (remainder a b)) 536870912.0 10.0)
  143. (test-call "2.0" (lambda (a b) (remainder a b)) 536870912.0 10)
  144. (test-call "2.0" (lambda (a b) (remainder a b)) 536870912 10.0)
  145. (test-call "3.0" (lambda (a b) (modulo a b)) 123.0 10.0)
  146. (test-call "3.0" (lambda (a b) (modulo a b)) 123.0 10)
  147. (test-call "3.0" (lambda (a b) (modulo a b)) 123 10.0)
  148. (test-call "2.0" (lambda (a b) (modulo a b)) 536870912.0 10.0)
  149. (test-call "2.0" (lambda (a b) (modulo a b)) 536870912.0 10)
  150. (test-call "2.0" (lambda (a b) (modulo a b)) 536870912 10.0)
  151. ;; Checks the different-sign adjustment in $mod's fixnum-fixnum case,
  152. ;; currently used only for modulo with a flonum argument (which calls
  153. ;; $mod directly, bypassing the fixnum fast path in `(hoot compile)').
  154. (test-call "-7.0" (lambda (a b) (modulo a b)) 123.0 -10.0)
  155. (test-call "-7.0" (lambda (a b) (modulo a b)) 123.0 -10)
  156. (test-call "-7.0" (lambda (a b) (modulo a b)) 123 -10.0)
  157. (test-call "7.0" (lambda (a b) (modulo a b)) -123.0 10.0)
  158. (test-call "7.0" (lambda (a b) (modulo a b)) -123.0 10)
  159. (test-call "7.0" (lambda (a b) (modulo a b)) -123 10.0)
  160. ;; truncating division
  161. (test-call "(2 1)"
  162. (lambda (a b) (call-with-values
  163. (lambda () (truncate/ a b))
  164. (lambda x x)))
  165. 5 2)
  166. (test-call "(-2 -1)"
  167. (lambda (a b) (call-with-values
  168. (lambda () (truncate/ a b))
  169. (lambda x x)))
  170. -5 2)
  171. (test-call "(-2 1)"
  172. (lambda (a b) (call-with-values
  173. (lambda () (truncate/ a b))
  174. (lambda x x)))
  175. 5 -2)
  176. (test-call "(2 -1)"
  177. (lambda (a b) (call-with-values
  178. (lambda () (truncate/ a b))
  179. (lambda x x)))
  180. -5 -2)
  181. (test-call "(2.0 -1.0)"
  182. (lambda (a b) (call-with-values
  183. (lambda () (truncate/ a b))
  184. (lambda x x)))
  185. -5.0 -2.0)
  186. (test-call "(2.0 -1.0)"
  187. (lambda (a b) (call-with-values
  188. (lambda () (truncate/ a b))
  189. (lambda x x)))
  190. -5.0 -2)
  191. (test-call "(2.0 -1.0)"
  192. (lambda (a b) (call-with-values
  193. (lambda () (truncate/ a b))
  194. (lambda x x)))
  195. -5 -2.0)
  196. (test-call "2" (lambda (a b) (truncate-quotient a b)) 5 2)
  197. (test-call "-2" (lambda (a b) (truncate-quotient a b)) -5 2)
  198. (test-call "-2" (lambda (a b) (truncate-quotient a b)) 5 -2)
  199. (test-call "2" (lambda (a b) (truncate-quotient a b)) -5 -2)
  200. (test-call "2.0" (lambda (a b) (truncate-quotient a b)) -5.0 -2.0)
  201. (test-call "2.0" (lambda (a b) (truncate-quotient a b)) -5.0 -2)
  202. (test-call "2.0" (lambda (a b) (truncate-quotient a b)) -5 -2.0)
  203. (test-call "1" (lambda (a b) (truncate-remainder a b)) 5 2)
  204. (test-call "-1" (lambda (a b) (truncate-remainder a b)) -5 2)
  205. (test-call "1" (lambda (a b) (truncate-remainder a b)) 5 -2)
  206. (test-call "-1" (lambda (a b) (truncate-remainder a b)) -5 -2)
  207. (test-call "-1.0" (lambda (a b) (truncate-remainder a b)) -5.0 -2.0)
  208. (test-call "-1.0" (lambda (a b) (truncate-remainder a b)) -5.0 -2)
  209. (test-call "-1.0" (lambda (a b) (truncate-remainder a b)) -5 -2.0)
  210. ;; flooring division
  211. (test-call "(2 1)" (lambda (a b) (call-with-values
  212. (lambda () (floor/ a b))
  213. (lambda x x)))
  214. 5 2)
  215. (test-call "(-3 1)" (lambda (a b) (call-with-values
  216. (lambda () (floor/ a b))
  217. (lambda x x)))
  218. -5 2)
  219. (test-call "(-3 -1)" (lambda (a b) (call-with-values
  220. (lambda () (floor/ a b))
  221. (lambda x x)))
  222. 5 -2)
  223. (test-call "(2 -1)" (lambda (a b) (call-with-values
  224. (lambda () (floor/ a b))
  225. (lambda x x)))
  226. -5 -2)
  227. (test-call "(2.0 -1.0)" (lambda (a b) (call-with-values
  228. (lambda () (floor/ a b))
  229. (lambda x x)))
  230. -5.0 -2.0)
  231. (test-call "(2.0 -1.0)" (lambda (a b) (call-with-values
  232. (lambda () (floor/ a b))
  233. (lambda x x)))
  234. -5.0 -2)
  235. (test-call "(2.0 -1.0)" (lambda (a b) (call-with-values
  236. (lambda () (floor/ a b))
  237. (lambda x x)))
  238. -5 -2.0)
  239. (test-call "2" (lambda (a b) (floor-quotient a b)) 5 2)
  240. (test-call "-3" (lambda (a b) (floor-quotient a b)) -5 2)
  241. (test-call "-3" (lambda (a b) (floor-quotient a b)) 5 -2)
  242. (test-call "2" (lambda (a b) (floor-quotient a b)) -5 -2)
  243. (test-call "2.0" (lambda (a b) (floor-quotient a b)) -5.0 -2.0)
  244. (test-call "2.0" (lambda (a b) (floor-quotient a b)) -5.0 -2)
  245. (test-call "2.0" (lambda (a b) (floor-quotient a b)) -5 -2.0)
  246. (test-call "1" (lambda (a b) (floor-remainder a b)) 5 2)
  247. (test-call "1" (lambda (a b) (floor-remainder a b)) -5 2)
  248. (test-call "-1" (lambda (a b) (floor-remainder a b)) 5 -2)
  249. (test-call "-1" (lambda (a b) (floor-remainder a b)) -5 -2)
  250. (test-call "-1.0" (lambda (a b) (floor-remainder a b)) -5.0 -2.0)
  251. (test-call "-1.0" (lambda (a b) (floor-remainder a b)) -5.0 -2)
  252. (test-call "-1.0" (lambda (a b) (floor-remainder a b)) -5 -2.0)
  253. ;; gcd and lcm
  254. (test-call "4" (lambda (a b) (gcd a b)) 32 -36)
  255. (test-call "0" (lambda () (gcd)))
  256. (test-call "288" (lambda (a b) (lcm a b)) 32 -36)
  257. (test-call "288.0" (lambda (a b) (lcm a b)) 32.0 -36)
  258. (test-call "1" (lambda () (lcm)))
  259. ;; rationalize
  260. (test-call "1/3" (lambda (a b) (rationalize a b)) 3/10 1/10)
  261. (test-call "1/4" (lambda (a b) (rationalize a b)) 2/10 1/10)
  262. (test-call "0.25" (lambda (a b) (rationalize a b)) 0.2 1/10)
  263. (test-call "0.25" (lambda (a b) (rationalize a b)) 2/10 0.1)
  264. ;; eta expansion
  265. (test-call "3" (lambda (f a b) (f a b)) + 1 2)
  266. (test-call "1" (lambda (f a b) (f a b)) - 2 1)
  267. (test-call "6" (lambda (f a b) (f a b)) * 2 3)
  268. (test-call "2" (lambda (f a b) (f a b)) / 6 3)
  269. ;; truncate
  270. (test-call "42" (lambda (x) (truncate x)) 42)
  271. (test-call "42.0" (lambda (x) (truncate x)) 42.3)
  272. (test-call "1" (lambda (x) (truncate x)) 43/42)
  273. (test-end* "test-numeric")