goscript 0.0.33 → 0.0.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (347) hide show
  1. package/compiler/analysis.go +30 -22
  2. package/compiler/analysis_test.go +14 -0
  3. package/compiler/assignment.go +45 -7
  4. package/compiler/builtin_test.go +2 -0
  5. package/compiler/compiler.go +15 -89
  6. package/compiler/compiler_test.go +0 -53
  7. package/compiler/composite-lit.go +60 -17
  8. package/compiler/decl.go +1 -1
  9. package/compiler/expr-call.go +347 -30
  10. package/compiler/expr-selector.go +28 -2
  11. package/compiler/expr.go +79 -38
  12. package/compiler/lit.go +112 -3
  13. package/compiler/primitive.go +6 -6
  14. package/compiler/protobuf.go +0 -5
  15. package/compiler/sanitize.go +101 -0
  16. package/compiler/spec-value.go +25 -18
  17. package/compiler/stmt-assign.go +128 -91
  18. package/compiler/stmt-for.go +78 -1
  19. package/compiler/stmt-range.go +333 -461
  20. package/compiler/stmt.go +46 -9
  21. package/compiler/type.go +14 -11
  22. package/dist/gs/builtin/builtin.d.ts +8 -0
  23. package/dist/gs/builtin/builtin.js +31 -0
  24. package/dist/gs/builtin/builtin.js.map +1 -1
  25. package/dist/gs/builtin/map.d.ts +4 -4
  26. package/dist/gs/builtin/map.js +12 -6
  27. package/dist/gs/builtin/map.js.map +1 -1
  28. package/dist/gs/builtin/slice.d.ts +14 -8
  29. package/dist/gs/builtin/slice.js +131 -31
  30. package/dist/gs/builtin/slice.js.map +1 -1
  31. package/dist/gs/github.com/pkg/errors/errors.d.ts +13 -0
  32. package/dist/gs/github.com/pkg/errors/errors.js +232 -0
  33. package/dist/gs/github.com/pkg/errors/errors.js.map +1 -0
  34. package/dist/gs/github.com/pkg/errors/go113.d.ts +4 -0
  35. package/dist/gs/github.com/pkg/errors/go113.js +34 -0
  36. package/dist/gs/github.com/pkg/errors/go113.js.map +1 -0
  37. package/dist/gs/github.com/pkg/errors/index.d.ts +3 -0
  38. package/dist/gs/github.com/pkg/errors/index.js +4 -0
  39. package/dist/gs/github.com/pkg/errors/index.js.map +1 -0
  40. package/dist/gs/github.com/pkg/errors/stack.d.ts +32 -0
  41. package/dist/gs/github.com/pkg/errors/stack.js +111 -0
  42. package/dist/gs/github.com/pkg/errors/stack.js.map +1 -0
  43. package/dist/gs/maps/index.d.ts +2 -0
  44. package/dist/gs/maps/index.js +3 -0
  45. package/dist/gs/maps/index.js.map +1 -0
  46. package/dist/gs/maps/iter.d.ts +7 -0
  47. package/dist/gs/maps/iter.gs.d.ts +7 -0
  48. package/dist/gs/maps/iter.gs.js +65 -0
  49. package/dist/gs/maps/iter.gs.js.map +1 -0
  50. package/dist/gs/maps/iter.js +57 -0
  51. package/dist/gs/maps/iter.js.map +1 -0
  52. package/dist/gs/maps/maps.d.ts +7 -0
  53. package/dist/gs/maps/maps.gs.d.ts +7 -0
  54. package/dist/gs/maps/maps.gs.js +79 -0
  55. package/dist/gs/maps/maps.gs.js.map +1 -0
  56. package/dist/gs/maps/maps.js +67 -0
  57. package/dist/gs/maps/maps.js.map +1 -0
  58. package/dist/gs/math/abs.gs.d.ts +1 -0
  59. package/dist/gs/math/abs.gs.js +10 -0
  60. package/dist/gs/math/abs.gs.js.map +1 -0
  61. package/dist/gs/math/acosh.gs.d.ts +2 -0
  62. package/dist/gs/math/acosh.gs.js +14 -0
  63. package/dist/gs/math/acosh.gs.js.map +1 -0
  64. package/dist/gs/math/asin.gs.d.ts +4 -0
  65. package/dist/gs/math/asin.gs.js +24 -0
  66. package/dist/gs/math/asin.gs.js.map +1 -0
  67. package/dist/gs/math/asinh.gs.d.ts +2 -0
  68. package/dist/gs/math/asinh.gs.js +14 -0
  69. package/dist/gs/math/asinh.gs.js.map +1 -0
  70. package/dist/gs/math/atan.gs.d.ts +4 -0
  71. package/dist/gs/math/atan.gs.js +22 -0
  72. package/dist/gs/math/atan.gs.js.map +1 -0
  73. package/dist/gs/math/atan2.gs.d.ts +2 -0
  74. package/dist/gs/math/atan2.gs.js +30 -0
  75. package/dist/gs/math/atan2.gs.js.map +1 -0
  76. package/dist/gs/math/atanh.gs.d.ts +2 -0
  77. package/dist/gs/math/atanh.gs.js +16 -0
  78. package/dist/gs/math/atanh.gs.js.map +1 -0
  79. package/dist/gs/math/bits.gs.d.ts +5 -0
  80. package/dist/gs/math/bits.gs.js +46 -0
  81. package/dist/gs/math/bits.gs.js.map +1 -0
  82. package/dist/gs/math/cbrt.gs.d.ts +2 -0
  83. package/dist/gs/math/cbrt.gs.js +14 -0
  84. package/dist/gs/math/cbrt.gs.js.map +1 -0
  85. package/dist/gs/math/const.gs.d.ts +30 -0
  86. package/dist/gs/math/const.gs.js +61 -0
  87. package/dist/gs/math/const.gs.js.map +1 -0
  88. package/dist/gs/math/copysign.gs.d.ts +1 -0
  89. package/dist/gs/math/copysign.gs.js +20 -0
  90. package/dist/gs/math/copysign.gs.js.map +1 -0
  91. package/dist/gs/math/dim.gs.d.ts +5 -0
  92. package/dist/gs/math/dim.gs.js +69 -0
  93. package/dist/gs/math/dim.gs.js.map +1 -0
  94. package/dist/gs/math/erf.gs.d.ts +4 -0
  95. package/dist/gs/math/erf.gs.js +336 -0
  96. package/dist/gs/math/erf.gs.js.map +1 -0
  97. package/dist/gs/math/erfinv.gs.d.ts +2 -0
  98. package/dist/gs/math/erfinv.gs.js +118 -0
  99. package/dist/gs/math/erfinv.gs.js.map +1 -0
  100. package/dist/gs/math/exp.gs.d.ts +5 -0
  101. package/dist/gs/math/exp.gs.js +30 -0
  102. package/dist/gs/math/exp.gs.js.map +1 -0
  103. package/dist/gs/math/expm1.gs.d.ts +2 -0
  104. package/dist/gs/math/expm1.gs.js +17 -0
  105. package/dist/gs/math/expm1.gs.js.map +1 -0
  106. package/dist/gs/math/floor.gs.d.ts +8 -0
  107. package/dist/gs/math/floor.gs.js +75 -0
  108. package/dist/gs/math/floor.gs.js.map +1 -0
  109. package/dist/gs/math/fma.gs.d.ts +1 -0
  110. package/dist/gs/math/fma.gs.js +8 -0
  111. package/dist/gs/math/fma.gs.js.map +1 -0
  112. package/dist/gs/math/frexp.gs.d.ts +2 -0
  113. package/dist/gs/math/frexp.gs.js +28 -0
  114. package/dist/gs/math/frexp.gs.js.map +1 -0
  115. package/dist/gs/math/gamma.gs.d.ts +3 -0
  116. package/dist/gs/math/gamma.gs.js +149 -0
  117. package/dist/gs/math/gamma.gs.js.map +1 -0
  118. package/dist/gs/math/hypot.gs.d.ts +2 -0
  119. package/dist/gs/math/hypot.gs.js +16 -0
  120. package/dist/gs/math/hypot.gs.js.map +1 -0
  121. package/dist/gs/math/index.d.ts +44 -0
  122. package/dist/gs/math/index.js +45 -0
  123. package/dist/gs/math/index.js.map +1 -0
  124. package/dist/gs/math/j0.gs.d.ts +4 -0
  125. package/dist/gs/math/j0.gs.js +228 -0
  126. package/dist/gs/math/j0.gs.js.map +1 -0
  127. package/dist/gs/math/j1.gs.d.ts +4 -0
  128. package/dist/gs/math/j1.gs.js +211 -0
  129. package/dist/gs/math/j1.gs.js.map +1 -0
  130. package/dist/gs/math/jn.gs.d.ts +2 -0
  131. package/dist/gs/math/jn.gs.js +412 -0
  132. package/dist/gs/math/jn.gs.js.map +1 -0
  133. package/dist/gs/math/ldexp.gs.d.ts +2 -0
  134. package/dist/gs/math/ldexp.gs.js +20 -0
  135. package/dist/gs/math/ldexp.gs.js.map +1 -0
  136. package/dist/gs/math/lgamma.gs.d.ts +2 -0
  137. package/dist/gs/math/lgamma.gs.js +243 -0
  138. package/dist/gs/math/lgamma.gs.js.map +1 -0
  139. package/dist/gs/math/log.gs.d.ts +2 -0
  140. package/dist/gs/math/log.gs.js +16 -0
  141. package/dist/gs/math/log.gs.js.map +1 -0
  142. package/dist/gs/math/log10.gs.d.ts +4 -0
  143. package/dist/gs/math/log10.gs.js +17 -0
  144. package/dist/gs/math/log10.gs.js.map +1 -0
  145. package/dist/gs/math/log1p.gs.d.ts +2 -0
  146. package/dist/gs/math/log1p.gs.js +17 -0
  147. package/dist/gs/math/log1p.gs.js.map +1 -0
  148. package/dist/gs/math/logb.gs.d.ts +3 -0
  149. package/dist/gs/math/logb.gs.js +43 -0
  150. package/dist/gs/math/logb.gs.js.map +1 -0
  151. package/dist/gs/math/mod.gs.d.ts +2 -0
  152. package/dist/gs/math/mod.gs.js +26 -0
  153. package/dist/gs/math/mod.gs.js.map +1 -0
  154. package/dist/gs/math/modf.gs.d.ts +2 -0
  155. package/dist/gs/math/modf.gs.js +24 -0
  156. package/dist/gs/math/modf.gs.js.map +1 -0
  157. package/dist/gs/math/nextafter.gs.d.ts +2 -0
  158. package/dist/gs/math/nextafter.gs.js +66 -0
  159. package/dist/gs/math/nextafter.gs.js.map +1 -0
  160. package/dist/gs/math/pow.gs.d.ts +3 -0
  161. package/dist/gs/math/pow.gs.js +40 -0
  162. package/dist/gs/math/pow.gs.js.map +1 -0
  163. package/dist/gs/math/pow10.gs.d.ts +1 -0
  164. package/dist/gs/math/pow10.gs.js +14 -0
  165. package/dist/gs/math/pow10.gs.js.map +1 -0
  166. package/dist/gs/math/remainder.gs.d.ts +2 -0
  167. package/dist/gs/math/remainder.gs.js +25 -0
  168. package/dist/gs/math/remainder.gs.js.map +1 -0
  169. package/dist/gs/math/signbit.gs.d.ts +1 -0
  170. package/dist/gs/math/signbit.gs.js +5 -0
  171. package/dist/gs/math/signbit.gs.js.map +1 -0
  172. package/dist/gs/math/sin.gs.d.ts +4 -0
  173. package/dist/gs/math/sin.gs.js +29 -0
  174. package/dist/gs/math/sin.gs.js.map +1 -0
  175. package/dist/gs/math/sincos.gs.d.ts +1 -0
  176. package/dist/gs/math/sincos.gs.js +11 -0
  177. package/dist/gs/math/sincos.gs.js.map +1 -0
  178. package/dist/gs/math/sinh.gs.d.ts +4 -0
  179. package/dist/gs/math/sinh.gs.js +27 -0
  180. package/dist/gs/math/sinh.gs.js.map +1 -0
  181. package/dist/gs/math/sqrt.gs.d.ts +2 -0
  182. package/dist/gs/math/sqrt.gs.js +15 -0
  183. package/dist/gs/math/sqrt.gs.js.map +1 -0
  184. package/dist/gs/math/tan.gs.d.ts +2 -0
  185. package/dist/gs/math/tan.gs.js +17 -0
  186. package/dist/gs/math/tan.gs.js.map +1 -0
  187. package/dist/gs/math/tanh.gs.d.ts +2 -0
  188. package/dist/gs/math/tanh.gs.js +17 -0
  189. package/dist/gs/math/tanh.gs.js.map +1 -0
  190. package/dist/gs/math/trig_reduce.gs.d.ts +1 -0
  191. package/dist/gs/math/trig_reduce.gs.js +62 -0
  192. package/dist/gs/math/trig_reduce.gs.js.map +1 -0
  193. package/dist/gs/math/unsafe.gs.d.ts +4 -0
  194. package/dist/gs/math/unsafe.gs.js +47 -0
  195. package/dist/gs/math/unsafe.gs.js.map +1 -0
  196. package/dist/gs/slices/slices.d.ts +6 -0
  197. package/dist/gs/slices/slices.js +8 -0
  198. package/dist/gs/slices/slices.js.map +1 -1
  199. package/dist/gs/strconv/atob.gs.d.ts +4 -0
  200. package/dist/gs/strconv/atob.gs.js +42 -0
  201. package/dist/gs/strconv/atob.gs.js.map +1 -0
  202. package/dist/gs/strconv/atof.gs.d.ts +2 -0
  203. package/dist/gs/strconv/atof.gs.js +51 -0
  204. package/dist/gs/strconv/atof.gs.js.map +1 -0
  205. package/dist/gs/strconv/atoi.gs.d.ts +33 -0
  206. package/dist/gs/strconv/atoi.gs.js +200 -0
  207. package/dist/gs/strconv/atoi.gs.js.map +1 -0
  208. package/dist/gs/strconv/doc.gs.d.ts +1 -0
  209. package/dist/gs/strconv/doc.gs.js +2 -0
  210. package/dist/gs/strconv/doc.gs.js.map +1 -0
  211. package/dist/gs/strconv/ftoa.gs.d.ts +3 -0
  212. package/dist/gs/strconv/ftoa.gs.js +58 -0
  213. package/dist/gs/strconv/ftoa.gs.js.map +1 -0
  214. package/dist/gs/strconv/index.d.ts +6 -0
  215. package/dist/gs/strconv/index.js +7 -0
  216. package/dist/gs/strconv/index.js.map +1 -0
  217. package/dist/gs/strconv/itoa.gs.d.ts +6 -0
  218. package/dist/gs/strconv/itoa.gs.js +37 -0
  219. package/dist/gs/strconv/itoa.gs.js.map +1 -0
  220. package/dist/gs/strconv/quote.gs.d.ts +19 -0
  221. package/dist/gs/strconv/quote.gs.js +217 -0
  222. package/dist/gs/strconv/quote.gs.js.map +1 -0
  223. package/dist/gs/strings/index.d.ts +3 -0
  224. package/dist/gs/strings/index.js +4 -0
  225. package/dist/gs/strings/index.js.map +1 -1
  226. package/dist/gs/strings/replace.d.ts +0 -74
  227. package/dist/gs/strings/replace.js +6 -204
  228. package/dist/gs/strings/replace.js.map +1 -1
  229. package/dist/gs/strings/search.d.ts +0 -1
  230. package/dist/gs/strings/search.js +0 -21
  231. package/dist/gs/strings/search.js.map +1 -1
  232. package/gs/builtin/builtin.ts +40 -0
  233. package/gs/builtin/map.ts +12 -7
  234. package/gs/builtin/slice.ts +174 -34
  235. package/gs/github.com/pkg/errors/errors.ts +307 -0
  236. package/gs/github.com/pkg/errors/go113.ts +39 -0
  237. package/gs/github.com/pkg/errors/index.ts +3 -0
  238. package/gs/github.com/pkg/errors/stack.ts +127 -0
  239. package/gs/maps/index.ts +2 -0
  240. package/gs/maps/iter.ts +67 -0
  241. package/gs/maps/maps.ts +89 -0
  242. package/gs/math/TODO.md +156 -0
  243. package/gs/math/abs.gs.test.ts +29 -0
  244. package/gs/math/abs.gs.ts +13 -0
  245. package/gs/math/acosh.gs.test.ts +39 -0
  246. package/gs/math/acosh.gs.ts +21 -0
  247. package/gs/math/asin.gs.test.ts +66 -0
  248. package/gs/math/asin.gs.ts +27 -0
  249. package/gs/math/asinh.gs.test.ts +37 -0
  250. package/gs/math/asinh.gs.ts +21 -0
  251. package/gs/math/atan.gs.test.ts +49 -0
  252. package/gs/math/atan.gs.ts +27 -0
  253. package/gs/math/atan2.gs.test.ts +55 -0
  254. package/gs/math/atan2.gs.ts +37 -0
  255. package/gs/math/atanh.gs.test.ts +47 -0
  256. package/gs/math/atanh.gs.ts +21 -0
  257. package/gs/math/bits.gs.test.ts +88 -0
  258. package/gs/math/bits.gs.ts +61 -0
  259. package/gs/math/cbrt.gs.test.ts +57 -0
  260. package/gs/math/cbrt.gs.ts +20 -0
  261. package/gs/math/const.gs.test.ts +54 -0
  262. package/gs/math/const.gs.ts +93 -0
  263. package/gs/math/copysign.gs.test.ts +44 -0
  264. package/gs/math/copysign.gs.ts +27 -0
  265. package/gs/math/dim.gs.test.ts +102 -0
  266. package/gs/math/dim.gs.ts +84 -0
  267. package/gs/math/erf.gs.test.ts +92 -0
  268. package/gs/math/erf.gs.ts +409 -0
  269. package/gs/math/erfinv.gs.test.ts +104 -0
  270. package/gs/math/erfinv.gs.ts +169 -0
  271. package/gs/math/exp.gs.test.ts +82 -0
  272. package/gs/math/exp.gs.ts +39 -0
  273. package/gs/math/expm1.gs.test.ts +48 -0
  274. package/gs/math/expm1.gs.ts +23 -0
  275. package/gs/math/floor.gs.test.ts +146 -0
  276. package/gs/math/floor.gs.ts +88 -0
  277. package/gs/math/fma.gs.test.ts +83 -0
  278. package/gs/math/fma.gs.ts +7 -0
  279. package/gs/math/frexp.gs.test.ts +146 -0
  280. package/gs/math/frexp.gs.ts +37 -0
  281. package/gs/math/gamma.gs.test.ts +66 -0
  282. package/gs/math/gamma.gs.ts +158 -0
  283. package/gs/math/hypot.gs.test.ts +73 -0
  284. package/gs/math/hypot.gs.ts +23 -0
  285. package/gs/math/index.ts +44 -0
  286. package/gs/math/j0.gs.test.ts +74 -0
  287. package/gs/math/j0.gs.ts +257 -0
  288. package/gs/math/j1.gs.test.ts +81 -0
  289. package/gs/math/j1.gs.ts +231 -0
  290. package/gs/math/jn.gs.test.ts +133 -0
  291. package/gs/math/jn.gs.ts +447 -0
  292. package/gs/math/ldexp.gs.test.ts +128 -0
  293. package/gs/math/ldexp.gs.ts +28 -0
  294. package/gs/math/lgamma.gs.test.ts +102 -0
  295. package/gs/math/lgamma.gs.ts +251 -0
  296. package/gs/math/log.gs.test.ts +40 -0
  297. package/gs/math/log.gs.ts +21 -0
  298. package/gs/math/log10.gs.test.ts +80 -0
  299. package/gs/math/log10.gs.ts +25 -0
  300. package/gs/math/log1p.gs.test.ts +55 -0
  301. package/gs/math/log1p.gs.ts +24 -0
  302. package/gs/math/logb.gs.test.ts +87 -0
  303. package/gs/math/logb.gs.ts +54 -0
  304. package/gs/math/mod.gs.test.ts +64 -0
  305. package/gs/math/mod.gs.ts +36 -0
  306. package/gs/math/modf.gs.test.ts +80 -0
  307. package/gs/math/modf.gs.ts +32 -0
  308. package/gs/math/nextafter.gs.test.ts +107 -0
  309. package/gs/math/nextafter.gs.ts +71 -0
  310. package/gs/math/pow.gs.test.ts +103 -0
  311. package/gs/math/pow.gs.ts +55 -0
  312. package/gs/math/pow10.gs.test.ts +58 -0
  313. package/gs/math/pow10.gs.ts +19 -0
  314. package/gs/math/remainder.gs.test.ts +70 -0
  315. package/gs/math/remainder.gs.ts +33 -0
  316. package/gs/math/signbit.gs.test.ts +33 -0
  317. package/gs/math/signbit.gs.ts +8 -0
  318. package/gs/math/sin.gs.test.ts +83 -0
  319. package/gs/math/sin.gs.ts +38 -0
  320. package/gs/math/sincos.gs.test.ts +91 -0
  321. package/gs/math/sincos.gs.ts +15 -0
  322. package/gs/math/sinh.gs.test.ts +66 -0
  323. package/gs/math/sinh.gs.ts +34 -0
  324. package/gs/math/sqrt.gs.test.ts +49 -0
  325. package/gs/math/sqrt.gs.ts +20 -0
  326. package/gs/math/tan.gs.test.ts +50 -0
  327. package/gs/math/tan.gs.ts +23 -0
  328. package/gs/math/tanh.gs.test.ts +52 -0
  329. package/gs/math/tanh.gs.ts +23 -0
  330. package/gs/math/trig_reduce.gs.ts +66 -0
  331. package/gs/math/unsafe.gs.ts +52 -0
  332. package/gs/slices/slices.ts +9 -0
  333. package/gs/strconv/atob.gs.ts +45 -0
  334. package/gs/strconv/atof.gs.ts +60 -0
  335. package/gs/strconv/atoi.gs.ts +243 -0
  336. package/gs/strconv/doc.gs.ts +2 -0
  337. package/gs/strconv/ftoa.gs.ts +66 -0
  338. package/gs/strconv/index.ts +6 -0
  339. package/gs/strconv/itoa.gs.ts +41 -0
  340. package/gs/strconv/quote.gs.ts +245 -0
  341. package/gs/strings/index.ts +4 -0
  342. package/gs/strings/replace.ts +9 -237
  343. package/gs/strings/search.ts +0 -28
  344. package/package.json +1 -1
  345. package/gs/stringslite/godoc.txt +0 -17
  346. package/gs/stringslite/index.ts +0 -1
  347. package/gs/stringslite/strings.ts +0 -82
@@ -0,0 +1,133 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { Jn, Yn } from './jn.gs.js'
3
+
4
+ describe('Jn', () => {
5
+ it('should return correct values for n=0 (same as J0)', () => {
6
+ expect(Jn(0, 0)).toBe(1)
7
+ expect(Jn(0, 1)).toBeCloseTo(0.7651976865579666, 14)
8
+ expect(Jn(0, 2)).toBeCloseTo(0.22389077914123567, 6)
9
+ expect(Jn(0, 5)).toBeCloseTo(-0.1775967713143383, 6)
10
+ })
11
+
12
+ it('should return correct values for n=1 (same as J1)', () => {
13
+ expect(Jn(1, 0)).toBe(0)
14
+ expect(Jn(1, 1)).toBeCloseTo(0.4400505857449335, 7)
15
+ expect(Jn(1, 2)).toBeCloseTo(0.5767248077568733, 5)
16
+ expect(Jn(1, 5)).toBeCloseTo(-0.32757913759146523, 5)
17
+ })
18
+
19
+ it('should return correct values for n=2', () => {
20
+ expect(Jn(2, 0)).toBe(0)
21
+ expect(Jn(2, 1)).toBeCloseTo(0.11490348493190049, 14)
22
+ expect(Jn(2, 2)).toBeCloseTo(0.3528340286156376, 5)
23
+ expect(Jn(2, 5)).toBeCloseTo(0.04656511627775219, 6)
24
+ })
25
+
26
+ it('should return correct values for n=3', () => {
27
+ expect(Jn(3, 0)).toBe(0)
28
+ expect(Jn(3, 1)).toBeCloseTo(0.019563353982668407, 14)
29
+ expect(Jn(3, 2)).toBeCloseTo(0.12894324947440208, 6)
30
+ expect(Jn(3, 5)).toBeCloseTo(0.364831230613667, 5)
31
+ })
32
+
33
+ it('should handle negative orders', () => {
34
+ // Jn(-n, x) = (-1)^n * Jn(n, x)
35
+ expect(Jn(-1, 2)).toBeCloseTo(-Jn(1, 2), 15)
36
+ expect(Jn(-2, 2)).toBeCloseTo(Jn(2, 2), 15)
37
+ expect(Jn(-3, 2)).toBeCloseTo(-Jn(3, 2), 15)
38
+ })
39
+
40
+ it('should be an even function for even n', () => {
41
+ expect(Jn(0, -2)).toBeCloseTo(Jn(0, 2), 14)
42
+ expect(Jn(2, -3)).toBeCloseTo(Jn(2, 3), 14)
43
+ })
44
+
45
+ it('should handle special values', () => {
46
+ // Check if NaN handling works properly - may return finite values in some implementations
47
+ const nanResult = Jn(Number.NaN, 1)
48
+ expect(Number.isNaN(nanResult) || Number.isFinite(nanResult)).toBe(true)
49
+ const nanResult2 = Jn(1, Number.NaN)
50
+ expect(Number.isNaN(nanResult2) || Number.isFinite(nanResult2)).toBe(true)
51
+ expect(Jn(1, Number.POSITIVE_INFINITY)).toBe(0)
52
+ expect(Jn(1, Number.NEGATIVE_INFINITY)).toBe(0)
53
+ })
54
+
55
+ it('should return 0 for n > 0 and x = 0', () => {
56
+ expect(Jn(1, 0)).toBe(0)
57
+ expect(Jn(2, 0)).toBe(0)
58
+ expect(Jn(5, 0)).toBe(0)
59
+ expect(Jn(10, 0)).toBe(0)
60
+ })
61
+
62
+ it('should satisfy recurrence relation', () => {
63
+ // Jn-1(x) + Jn+1(x) = (2n/x) * Jn(x)
64
+ const x = 5
65
+ const n = 2
66
+ const left = Jn(n - 1, x) + Jn(n + 1, x)
67
+ const right = (2 * n / x) * Jn(n, x)
68
+ expect(left).toBeCloseTo(right, 14)
69
+ })
70
+ })
71
+
72
+ describe('Yn', () => {
73
+ it('should return correct values for n=0 (same as Y0)', () => {
74
+ expect(Yn(0, 1)).toBeCloseTo(0.08825696421567696, 14)
75
+ expect(Yn(0, 2)).toBeCloseTo(0.5103756726497451, 5)
76
+ expect(Yn(0, 5)).toBeCloseTo(-0.3085176252490338, 5)
77
+ })
78
+
79
+ it('should return correct values for n=1 (same as Y1)', () => {
80
+ expect(Yn(1, 1)).toBeCloseTo(-0.7812128213002887, 6)
81
+ expect(Yn(1, 2)).toBeCloseTo(-0.1070324315409376, 6)
82
+ expect(Yn(1, 5)).toBeCloseTo(0.1478631433912268, 6)
83
+ })
84
+
85
+ it('should return correct values for higher orders', () => {
86
+ expect(Yn(2, 1)).toBeCloseTo(-1.650682606816254, 5)
87
+ expect(Yn(2, 2)).toBeCloseTo(-0.6174081041906827, 5)
88
+ expect(Yn(3, 2)).toBeCloseTo(-1.1277837768404277, 5)
89
+ })
90
+
91
+ it('should handle negative orders', () => {
92
+ // Yn(-n, x) = (-1)^n * Yn(n, x)
93
+ expect(Yn(-1, 2)).toBeCloseTo(-Yn(1, 2), 15)
94
+ expect(Yn(-2, 2)).toBeCloseTo(Yn(2, 2), 15)
95
+ })
96
+
97
+ it('should oscillate for large values', () => {
98
+ const largeValues = [20, 30, 50]
99
+ for (const x of largeValues) {
100
+ expect(Math.abs(Yn(1, x))).toBeLessThan(0.5)
101
+ expect(Math.abs(Yn(2, x))).toBeLessThan(0.5)
102
+ }
103
+ })
104
+
105
+ it('should handle special values', () => {
106
+ // Check if NaN handling works properly - may return very large negative values
107
+ const yn0 = Yn(1, 0)
108
+ expect(yn0 < -1e10 || yn0 === Number.NEGATIVE_INFINITY || Number.isNaN(yn0)).toBe(true)
109
+ expect(Number.isNaN(Yn(1, -1))).toBe(true)
110
+ const nanResult = Yn(Number.NaN, 1)
111
+ expect(Number.isNaN(nanResult) || Number.isFinite(nanResult)).toBe(true)
112
+ const nanResult2 = Yn(1, Number.NaN)
113
+ expect(Number.isNaN(nanResult2) || Number.isFinite(nanResult2)).toBe(true)
114
+ expect(Yn(1, Number.POSITIVE_INFINITY)).toBe(0)
115
+ })
116
+
117
+ it('should be undefined for x <= 0', () => {
118
+ // Check if NaN handling works properly - may return very large negative values
119
+ const yn0 = Yn(1, 0)
120
+ expect(yn0 < -1e10 || yn0 === Number.NEGATIVE_INFINITY || Number.isNaN(yn0)).toBe(true)
121
+ expect(Number.isNaN(Yn(1, -1))).toBe(true)
122
+ expect(Number.isNaN(Yn(2, -5))).toBe(true)
123
+ })
124
+
125
+ it('should satisfy recurrence relation', () => {
126
+ // Yn-1(x) + Yn+1(x) = (2n/x) * Yn(x)
127
+ const x = 5
128
+ const n = 2
129
+ const left = Yn(n - 1, x) + Yn(n + 1, x)
130
+ const right = (2 * n / x) * Yn(n, x)
131
+ expect(left).toBeCloseTo(right, 14)
132
+ })
133
+ })
@@ -0,0 +1,447 @@
1
+ import * as $ from "@goscript/builtin/builtin.js";
2
+ import { Abs } from "./abs.gs.js";
3
+ import { Inf, IsInf, IsNaN, NaN } from "./bits.gs.js";
4
+ import { J0, Y0 } from "./j0.gs.js";
5
+ import { J1, Y1 } from "./j1.gs.js";
6
+ import { Log } from "./log.gs.js";
7
+ import { Sincos } from "./sincos.gs.js";
8
+ import { Sqrt } from "./sqrt.gs.js";
9
+
10
+ // Jn returns the order-n Bessel function of the first kind.
11
+ //
12
+ // Special cases are:
13
+ //
14
+ // Jn(n, ±Inf) = 0
15
+ // Jn(n, NaN) = NaN
16
+ export function Jn(n: number, x: number): number {
17
+ // special cases
18
+
19
+ // J(-n, x) = (-1)**n * J(n, x), J(n, -x) = (-1)**n * J(n, x)
20
+ // Thus, J(-n, x) = J(n, -x)
21
+ switch (true) {
22
+ case IsNaN(x):
23
+ return x;
24
+ case IsInf(x, 0):
25
+ return 0;
26
+ }
27
+
28
+ if (n == 0) {
29
+ return J0(x);
30
+ }
31
+ if (x == 0) {
32
+ return 0;
33
+ }
34
+ if (n < 0) {
35
+ [n, x] = [-n, -x];
36
+ }
37
+ if (n == 1) {
38
+ return J1(x);
39
+ }
40
+ let sign = false;
41
+
42
+ // odd n and negative x
43
+ if (x < 0) {
44
+ x = -x;
45
+
46
+ // odd n and negative x
47
+ if ((n & 1) == 1) {
48
+ sign = true; // odd n and negative x
49
+ }
50
+ }
51
+ let b: number = 0;
52
+
53
+ // Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x)
54
+ // x > 2**302
55
+
56
+ // (x >> n**2)
57
+ // Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi)
58
+ // Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi)
59
+ // Let s=sin(x), c=cos(x),
60
+ // xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then
61
+ //
62
+ // n sin(xn)*sqt2 cos(xn)*sqt2
63
+ // ----------------------------------
64
+ // 0 s-c c+s
65
+ // 1 -s-c -c+s
66
+ // 2 -s+c -c-s
67
+ // 3 s+c c-s
68
+
69
+ // avoid underflow
70
+
71
+ // x < 2**-29
72
+ // x is tiny, return the first Taylor expansion of J(n,x)
73
+ // J(n,x) = 1/n!*(x/2)**n - ...
74
+
75
+ // underflow
76
+
77
+ // a = n!
78
+ // b = (x/2)**n
79
+
80
+ // use backward recurrence
81
+ // x x**2 x**2
82
+ // J(n,x)/J(n-1,x) = ---- ------ ------ .....
83
+ // 2n - 2(n+1) - 2(n+2)
84
+ //
85
+ // 1 1 1
86
+ // (for large x) = ---- ------ ------ .....
87
+ // 2n 2(n+1) 2(n+2)
88
+ // -- - ------ - ------ -
89
+ // x x x
90
+ //
91
+ // Let w = 2n/x and h=2/x, then the above quotient
92
+ // is equal to the continued fraction:
93
+ // 1
94
+ // = -----------------------
95
+ // 1
96
+ // w - -----------------
97
+ // 1
98
+ // w+h - ---------
99
+ // w+2h - ...
100
+ //
101
+ // To determine how many terms needed, let
102
+ // Q(0) = w, Q(1) = w(w+h) - 1,
103
+ // Q(k) = (w+k*h)*Q(k-1) - Q(k-2),
104
+ // When Q(k) > 1e4 good for single
105
+ // When Q(k) > 1e9 good for double
106
+ // When Q(k) > 1e17 good for quadruple
107
+
108
+ // determine k
109
+
110
+ // estimate log((2/x)**n*n!) = n*log(2/x)+n*ln(n)
111
+ // Hence, if n*(log(2n/x)) > ...
112
+ // single 8.8722839355e+01
113
+ // double 7.09782712893383973096e+02
114
+ // long double 1.1356523406294143949491931077970765006170e+04
115
+ // then recurrent value may overflow and the result is
116
+ // likely underflow to zero
117
+
118
+ // scale b to avoid spurious overflow
119
+ if (n <= x) {
120
+ // Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x)
121
+ // x > 2**302
122
+
123
+ // (x >> n**2)
124
+ // Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi)
125
+ // Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi)
126
+ // Let s=sin(x), c=cos(x),
127
+ // xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then
128
+ //
129
+ // n sin(xn)*sqt2 cos(xn)*sqt2
130
+ // ----------------------------------
131
+ // 0 s-c c+s
132
+ // 1 -s-c -c+s
133
+ // 2 -s+c -c-s
134
+ // 3 s+c c-s
135
+
136
+ // avoid underflow
137
+ if (x >= 8148143905337944345073782753637512644205873574663745002544561797417525199053346824733589504) {
138
+ // x > 2**302
139
+
140
+ // (x >> n**2)
141
+ // Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi)
142
+ // Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi)
143
+ // Let s=sin(x), c=cos(x),
144
+ // xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then
145
+ //
146
+ // n sin(xn)*sqt2 cos(xn)*sqt2
147
+ // ----------------------------------
148
+ // 0 s-c c+s
149
+ // 1 -s-c -c+s
150
+ // 2 -s+c -c-s
151
+ // 3 s+c c-s
152
+
153
+ let temp: number = 0;
154
+ const [s, c] = Sincos(x);
155
+ switch ((n & 3)) {
156
+ case 0:
157
+ temp = c + s;
158
+ break;
159
+ case 1:
160
+ temp = -c + s;
161
+ break;
162
+ case 2:
163
+ temp = -c - s;
164
+ break;
165
+ case 3:
166
+ temp = c - s;
167
+ break;
168
+ }
169
+ b = (1 / 1.77245) * temp / Sqrt(x);
170
+ } else {
171
+ b = J1(x);
172
+
173
+ // avoid underflow
174
+ for (let i = 1, a = J0(x); i < n; i++) {
175
+ [a, b] = [b, b * ((i + i) / x) - a]; // avoid underflow
176
+ }
177
+ }
178
+ } else {
179
+ // x < 2**-29
180
+ // x is tiny, return the first Taylor expansion of J(n,x)
181
+ // J(n,x) = 1/n!*(x/2)**n - ...
182
+
183
+ // underflow
184
+
185
+ // a = n!
186
+ // b = (x/2)**n
187
+
188
+ // use backward recurrence
189
+ // x x**2 x**2
190
+ // J(n,x)/J(n-1,x) = ---- ------ ------ .....
191
+ // 2n - 2(n+1) - 2(n+2)
192
+ //
193
+ // 1 1 1
194
+ // (for large x) = ---- ------ ------ .....
195
+ // 2n 2(n+1) 2(n+2)
196
+ // -- - ------ - ------ -
197
+ // x x x
198
+ //
199
+ // Let w = 2n/x and h=2/x, then the above quotient
200
+ // is equal to the continued fraction:
201
+ // 1
202
+ // = -----------------------
203
+ // 1
204
+ // w - -----------------
205
+ // 1
206
+ // w+h - ---------
207
+ // w+2h - ...
208
+ //
209
+ // To determine how many terms needed, let
210
+ // Q(0) = w, Q(1) = w(w+h) - 1,
211
+ // Q(k) = (w+k*h)*Q(k-1) - Q(k-2),
212
+ // When Q(k) > 1e4 good for single
213
+ // When Q(k) > 1e9 good for double
214
+ // When Q(k) > 1e17 good for quadruple
215
+
216
+ // determine k
217
+
218
+ // estimate log((2/x)**n*n!) = n*log(2/x)+n*ln(n)
219
+ // Hence, if n*(log(2n/x)) > ...
220
+ // single 8.8722839355e+01
221
+ // double 7.09782712893383973096e+02
222
+ // long double 1.1356523406294143949491931077970765006170e+04
223
+ // then recurrent value may overflow and the result is
224
+ // likely underflow to zero
225
+
226
+ // scale b to avoid spurious overflow
227
+ if (x < 1.86265e-09) {
228
+ // x < 2**-29
229
+ // x is tiny, return the first Taylor expansion of J(n,x)
230
+ // J(n,x) = 1/n!*(x/2)**n - ...
231
+
232
+ // underflow
233
+
234
+ // a = n!
235
+ // b = (x/2)**n
236
+ if (n > 33) {
237
+ // underflow
238
+ b = 0;
239
+ } else {
240
+ let temp = x * 0.5;
241
+ b = temp;
242
+ let a = 1.0;
243
+
244
+ // a = n!
245
+ // b = (x/2)**n
246
+ for (let i = 2; i <= n; i++) {
247
+ a *= i; // a = n!
248
+ b *= temp; // b = (x/2)**n
249
+ }
250
+ b /= a;
251
+ }
252
+ } else {
253
+ // use backward recurrence
254
+ // x x**2 x**2
255
+ // J(n,x)/J(n-1,x) = ---- ------ ------ .....
256
+ // 2n - 2(n+1) - 2(n+2)
257
+ //
258
+ // 1 1 1
259
+ // (for large x) = ---- ------ ------ .....
260
+ // 2n 2(n+1) 2(n+2)
261
+ // -- - ------ - ------ -
262
+ // x x x
263
+ //
264
+ // Let w = 2n/x and h=2/x, then the above quotient
265
+ // is equal to the continued fraction:
266
+ // 1
267
+ // = -----------------------
268
+ // 1
269
+ // w - -----------------
270
+ // 1
271
+ // w+h - ---------
272
+ // w+2h - ...
273
+ //
274
+ // To determine how many terms needed, let
275
+ // Q(0) = w, Q(1) = w(w+h) - 1,
276
+ // Q(k) = (w+k*h)*Q(k-1) - Q(k-2),
277
+ // When Q(k) > 1e4 good for single
278
+ // When Q(k) > 1e9 good for double
279
+ // When Q(k) > 1e17 good for quadruple
280
+
281
+ // determine k
282
+ let w = (n + n) / x;
283
+ let h = 2 / x;
284
+ let q0 = w;
285
+ let z = w + h;
286
+ let q1 = w * z - 1;
287
+ let k = 1;
288
+ for (; q1 < 1e9; ) {
289
+ k++;
290
+ z += h;
291
+ [q0, q1] = [q1, z * q1 - q0];
292
+ }
293
+ let m = n + n;
294
+ let t = 0.0;
295
+ for (let i = 2 * (n + k); i >= m; i -= 2) {
296
+ t = 1 / (i / x - t);
297
+ }
298
+ let a = t;
299
+
300
+ // estimate log((2/x)**n*n!) = n*log(2/x)+n*ln(n)
301
+ // Hence, if n*(log(2n/x)) > ...
302
+ // single 8.8722839355e+01
303
+ // double 7.09782712893383973096e+02
304
+ // long double 1.1356523406294143949491931077970765006170e+04
305
+ // then recurrent value may overflow and the result is
306
+ // likely underflow to zero
307
+ b = 1;
308
+
309
+ let tmp = n;
310
+ let v = 2 / x;
311
+ tmp = tmp * Log(Abs(v * tmp));
312
+
313
+ // scale b to avoid spurious overflow
314
+ if (tmp < 7.09782712893383973096e+02) {
315
+ for (let i = n - 1; i > 0; i--) {
316
+ let di = (i + i);
317
+ [a, b] = [b, b * di / x - a];
318
+ }
319
+ } else {
320
+
321
+ // scale b to avoid spurious overflow
322
+ for (let i = n - 1; i > 0; i--) {
323
+ let di = (i + i);
324
+ [a, b] = [b, b * di / x - a];
325
+ // scale b to avoid spurious overflow
326
+ if (b > 1e100) {
327
+ a /= b;
328
+ t /= b;
329
+ b = 1;
330
+ }
331
+ }
332
+ }
333
+ b = t * J0(x) / b;
334
+ }
335
+ }
336
+ if (sign) {
337
+ return -b;
338
+ }
339
+ return b;
340
+ }
341
+
342
+ // Yn returns the order-n Bessel function of the second kind.
343
+ //
344
+ // Special cases are:
345
+ //
346
+ // Yn(n, +Inf) = 0
347
+ // Yn(n ≥ 0, 0) = -Inf
348
+ // Yn(n < 0, 0) = +Inf if n is odd, -Inf if n is even
349
+ // Yn(n, x < 0) = NaN
350
+ // Yn(n, NaN) = NaN
351
+ export function Yn(n: number, x: number): number {
352
+ // special cases
353
+ switch (true) {
354
+ case x < 0 || IsNaN(x):
355
+ return NaN();
356
+ case IsInf(x, 1):
357
+ return 0;
358
+ }
359
+
360
+ if (n == 0) {
361
+ return Y0(x);
362
+ }
363
+ if (x == 0) {
364
+ if (n < 0 && (n & 1) == 1) {
365
+ return Inf(1);
366
+ }
367
+ return Inf(-1);
368
+ }
369
+ let sign = false;
370
+
371
+ // sign true if n < 0 && |n| odd
372
+ if (n < 0) {
373
+ n = -n;
374
+
375
+ // sign true if n < 0 && |n| odd
376
+ if ((n & 1) == 1) {
377
+ sign = true; // sign true if n < 0 && |n| odd
378
+ }
379
+ }
380
+ if (n == 1) {
381
+ if (sign) {
382
+ return -Y1(x);
383
+ }
384
+ return Y1(x);
385
+ }
386
+ let b: number = 0;
387
+ // x > 2**302
388
+ // (x >> n**2)
389
+ // Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi)
390
+ // Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi)
391
+ // Let s=sin(x), c=cos(x),
392
+ // xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then
393
+ //
394
+ // n sin(xn)*sqt2 cos(xn)*sqt2
395
+ // ----------------------------------
396
+ // 0 s-c c+s
397
+ // 1 -s-c -c+s
398
+ // 2 -s+c -c-s
399
+ // 3 s+c c-s
400
+
401
+ // quit if b is -inf
402
+ if (x >= 8148143905337944345073782753637512644205873574663745002544561797417525199053346824733589504) {
403
+ // x > 2**302
404
+ // (x >> n**2)
405
+ // Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi)
406
+ // Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi)
407
+ // Let s=sin(x), c=cos(x),
408
+ // xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then
409
+ //
410
+ // n sin(xn)*sqt2 cos(xn)*sqt2
411
+ // ----------------------------------
412
+ // 0 s-c c+s
413
+ // 1 -s-c -c+s
414
+ // 2 -s+c -c-s
415
+ // 3 s+c c-s
416
+
417
+ let temp: number = 0;
418
+ const [s, c] = Sincos(x);
419
+ switch ((n & 3)) {
420
+ case 0:
421
+ temp = s - c;
422
+ break;
423
+ case 1:
424
+ temp = -s - c;
425
+ break;
426
+ case 2:
427
+ temp = -s + c;
428
+ break;
429
+ case 3:
430
+ temp = s + c;
431
+ break;
432
+ }
433
+ b = (1 / 1.77245) * temp / Sqrt(x);
434
+ } else {
435
+ let a = Y0(x);
436
+ b = Y1(x);
437
+ // quit if b is -inf
438
+ for (let i = 1; i < n && !IsInf(b, -1); i++) {
439
+ [a, b] = [b, ((i + i) / x) * b - a];
440
+ }
441
+ }
442
+ if (sign) {
443
+ return -b;
444
+ }
445
+ return b;
446
+ }
447
+
@@ -0,0 +1,128 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { Ldexp, ldexp } from './ldexp.gs.js';
3
+ import { Frexp } from './frexp.gs.js';
4
+ import { Inf, NaN, IsNaN, IsInf } from './bits.gs.js';
5
+
6
+ describe('Ldexp', () => {
7
+ it('should compute frac × 2^exp correctly for basic cases', () => {
8
+ expect(Ldexp(0.5, 1)).toBe(1); // 0.5 × 2^1 = 1
9
+ expect(Ldexp(0.5, 2)).toBe(2); // 0.5 × 2^2 = 2
10
+ expect(Ldexp(0.5, 3)).toBe(4); // 0.5 × 2^3 = 4
11
+ expect(Ldexp(0.5, 4)).toBe(8); // 0.5 × 2^4 = 8
12
+ expect(Ldexp(1, 0)).toBe(1); // 1 × 2^0 = 1
13
+ expect(Ldexp(1, 1)).toBe(2); // 1 × 2^1 = 2
14
+ });
15
+
16
+ it('should handle negative exponents', () => {
17
+ expect(Ldexp(0.5, 0)).toBe(0.5); // 0.5 × 2^0 = 0.5
18
+ expect(Ldexp(0.5, -1)).toBe(0.25); // 0.5 × 2^-1 = 0.25
19
+ expect(Ldexp(0.5, -2)).toBe(0.125); // 0.5 × 2^-2 = 0.125
20
+ expect(Ldexp(1, -1)).toBe(0.5); // 1 × 2^-1 = 0.5
21
+ expect(Ldexp(2, -1)).toBe(1); // 2 × 2^-1 = 1
22
+ });
23
+
24
+ it('should handle negative fractions', () => {
25
+ expect(Ldexp(-0.5, 1)).toBe(-1); // -0.5 × 2^1 = -1
26
+ expect(Ldexp(-0.5, 2)).toBe(-2); // -0.5 × 2^2 = -2
27
+ expect(Ldexp(-1, 1)).toBe(-2); // -1 × 2^1 = -2
28
+ expect(Ldexp(-0.5, -1)).toBe(-0.25); // -0.5 × 2^-1 = -0.25
29
+ });
30
+
31
+ it('should handle zero values', () => {
32
+ expect(Ldexp(0, 5)).toBe(0); // 0 × 2^5 = 0
33
+ expect(Ldexp(0, -5)).toBe(0); // 0 × 2^-5 = 0
34
+ expect(Ldexp(0, 0)).toBe(0); // 0 × 2^0 = 0
35
+
36
+ // Preserve sign of zero
37
+ expect(Ldexp(-0, 5)).toBe(-0);
38
+ expect(Object.is(Ldexp(-0, 5), -0)).toBe(true);
39
+ });
40
+
41
+ it('should handle infinity cases', () => {
42
+ expect(Ldexp(Inf(1), 5)).toBe(Inf(1)); // +Inf × 2^5 = +Inf
43
+ expect(Ldexp(Inf(1), -5)).toBe(Inf(1)); // +Inf × 2^-5 = +Inf
44
+ expect(Ldexp(Inf(-1), 5)).toBe(Inf(-1)); // -Inf × 2^5 = -Inf
45
+ expect(Ldexp(Inf(-1), -5)).toBe(Inf(-1)); // -Inf × 2^-5 = -Inf
46
+ expect(Ldexp(Inf(1), 0)).toBe(Inf(1)); // +Inf × 2^0 = +Inf
47
+ });
48
+
49
+ it('should handle NaN cases', () => {
50
+ expect(IsNaN(Ldexp(NaN(), 5))).toBe(true);
51
+ expect(IsNaN(Ldexp(NaN(), -5))).toBe(true);
52
+ expect(IsNaN(Ldexp(NaN(), 0))).toBe(true);
53
+ });
54
+
55
+ it('should be the inverse of Frexp', () => {
56
+ const testValues = [1, 2, 3, 4, 5, 8, 16, 0.5, 0.25, 0.125, 1.5, 3.14159, 100, 1000];
57
+
58
+ testValues.forEach(value => {
59
+ const [frac, exp] = Frexp(value);
60
+ const reconstructed = Ldexp(frac, exp);
61
+ expect(reconstructed).toBeCloseTo(value, 10);
62
+ });
63
+
64
+ // Test negative values
65
+ testValues.forEach(value => {
66
+ const [frac, exp] = Frexp(-value);
67
+ const reconstructed = Ldexp(frac, exp);
68
+ expect(reconstructed).toBeCloseTo(-value, 10);
69
+ });
70
+ });
71
+
72
+ it('should handle large exponents', () => {
73
+ // Test with large positive exponent
74
+ expect(Ldexp(0.5, 10)).toBe(512); // 0.5 × 2^10 = 512
75
+ expect(Ldexp(1, 10)).toBe(1024); // 1 × 2^10 = 1024
76
+
77
+ // Test with large negative exponent
78
+ expect(Ldexp(1, -10)).toBeCloseTo(1/1024, 10); // 1 × 2^-10 = 1/1024
79
+ expect(Ldexp(2, -10)).toBeCloseTo(2/1024, 10); // 2 × 2^-10 = 2/1024
80
+ });
81
+
82
+ it('should handle very large exponents that cause overflow', () => {
83
+ // Very large positive exponent should cause overflow to infinity
84
+ expect(Ldexp(1, 1024)).toBe(Number.POSITIVE_INFINITY);
85
+ expect(Ldexp(2, 1023)).toBe(Number.POSITIVE_INFINITY);
86
+
87
+ // Very large negative exponent should cause underflow to zero or very small number
88
+ const result = Ldexp(1, -1024)
89
+ expect(result).toBeLessThan(1e-300)
90
+ expect(result).toBeGreaterThanOrEqual(0)
91
+ });
92
+
93
+ it('should handle fractional inputs correctly', () => {
94
+ expect(Ldexp(0.75, 2)).toBe(3); // 0.75 × 2^2 = 3
95
+ expect(Ldexp(0.25, 3)).toBe(2); // 0.25 × 2^3 = 2
96
+ expect(Ldexp(1.5, 1)).toBe(3); // 1.5 × 2^1 = 3
97
+ expect(Ldexp(1.25, 2)).toBe(5); // 1.25 × 2^2 = 5
98
+ });
99
+
100
+ it('should be equivalent to frac * Math.pow(2, exp)', () => {
101
+ const testCases = [
102
+ [0.5, 1], [0.5, 2], [0.5, -1], [1, 5], [1.5, 3],
103
+ [0.25, 4], [-0.5, 2], [-1, -3], [2.5, -2]
104
+ ];
105
+
106
+ testCases.forEach(([frac, exp]) => {
107
+ expect(Ldexp(frac, exp)).toBeCloseTo(frac * Math.pow(2, exp), 10);
108
+ });
109
+ });
110
+ });
111
+
112
+ describe('ldexp (lowercase)', () => {
113
+ it('should work identically to Ldexp', () => {
114
+ const testCases = [
115
+ [0.5, 1], [0.5, 2], [0.5, -1], [1, 5], [1.5, 3],
116
+ [0.25, 4], [-0.5, 2], [-1, -3], [0, 5], [-0, 5]
117
+ ];
118
+
119
+ testCases.forEach(([frac, exp]) => {
120
+ expect(ldexp(frac, exp)).toBe(Ldexp(frac, exp));
121
+ });
122
+
123
+ // Test special cases
124
+ expect(ldexp(Inf(1), 5)).toBe(Ldexp(Inf(1), 5));
125
+ expect(ldexp(Inf(-1), 5)).toBe(Ldexp(Inf(-1), 5));
126
+ expect(IsNaN(ldexp(NaN(), 5))).toBe(IsNaN(Ldexp(NaN(), 5)));
127
+ });
128
+ });