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,83 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { FMA } from './fma.gs.js';
3
+ import { Inf, NaN, IsNaN, IsInf } from './bits.gs.js';
4
+
5
+ describe('FMA', () => {
6
+ it('should compute fused multiply-add correctly for basic cases', () => {
7
+ expect(FMA(2, 3, 4)).toBe(10); // 2*3 + 4 = 10
8
+ expect(FMA(1.5, 2, 0.5)).toBe(3.5); // 1.5*2 + 0.5 = 3.5
9
+ expect(FMA(0.1, 0.2, 0.3)).toBeCloseTo(0.32, 10); // 0.1*0.2 + 0.3 = 0.32
10
+ expect(FMA(-2, 3, 1)).toBe(-5); // -2*3 + 1 = -5
11
+ });
12
+
13
+ it('should handle zero values', () => {
14
+ expect(FMA(0, 5, 3)).toBe(3); // 0*5 + 3 = 3
15
+ expect(FMA(5, 0, 3)).toBe(3); // 5*0 + 3 = 3
16
+ expect(FMA(5, 3, 0)).toBe(15); // 5*3 + 0 = 15
17
+ expect(FMA(0, 0, 0)).toBe(0); // 0*0 + 0 = 0
18
+ expect(FMA(0, 0, 5)).toBe(5); // 0*0 + 5 = 5
19
+ });
20
+
21
+ it('should handle negative values', () => {
22
+ expect(FMA(-2, -3, 4)).toBe(10); // -2*-3 + 4 = 10
23
+ expect(FMA(-2, 3, -4)).toBe(-10); // -2*3 + -4 = -10
24
+ expect(FMA(2, -3, -4)).toBe(-10); // 2*-3 + -4 = -10
25
+ expect(FMA(-2, -3, -4)).toBe(2); // -2*-3 + -4 = 2
26
+ });
27
+
28
+ it('should handle infinity cases', () => {
29
+ expect(FMA(Inf(1), 2, 3)).toBe(Inf(1)); // +Inf * 2 + 3 = +Inf
30
+ expect(FMA(2, Inf(1), 3)).toBe(Inf(1)); // 2 * +Inf + 3 = +Inf
31
+ expect(FMA(2, 3, Inf(1))).toBe(Inf(1)); // 2 * 3 + +Inf = +Inf
32
+ expect(FMA(Inf(-1), 2, 3)).toBe(Inf(-1)); // -Inf * 2 + 3 = -Inf
33
+ expect(FMA(Inf(1), Inf(1), 3)).toBe(Inf(1)); // +Inf * +Inf + 3 = +Inf
34
+ expect(FMA(Inf(-1), Inf(-1), 3)).toBe(Inf(1)); // -Inf * -Inf + 3 = +Inf
35
+ });
36
+
37
+ it('should handle NaN cases', () => {
38
+ expect(IsNaN(FMA(NaN(), 2, 3))).toBe(true);
39
+ expect(IsNaN(FMA(2, NaN(), 3))).toBe(true);
40
+ expect(IsNaN(FMA(2, 3, NaN()))).toBe(true);
41
+ expect(IsNaN(FMA(NaN(), NaN(), NaN()))).toBe(true);
42
+ });
43
+
44
+ it('should handle special infinity and zero combinations', () => {
45
+ // Inf * 0 should produce NaN
46
+ expect(IsNaN(FMA(Inf(1), 0, 5))).toBe(true);
47
+ expect(IsNaN(FMA(0, Inf(1), 5))).toBe(true);
48
+
49
+ // But if the addition part is also infinity, behavior depends on implementation
50
+ expect(IsNaN(FMA(Inf(1), 0, Inf(1)))).toBe(true);
51
+ });
52
+
53
+ it('should handle cancellation cases', () => {
54
+ // Cases where x*y and z cancel out
55
+ expect(FMA(2, 3, -6)).toBe(0); // 2*3 + (-6) = 0
56
+ expect(FMA(-5, 4, 20)).toBe(0); // -5*4 + 20 = 0
57
+ expect(FMA(0.5, 0.2, -0.1)).toBeCloseTo(0, 10); // 0.5*0.2 + (-0.1) = 0
58
+ });
59
+
60
+ it('should handle very large and small numbers', () => {
61
+ const large = 1e100;
62
+ const small = 1e-100;
63
+
64
+ // Relax tolerance for very large/small number calculations
65
+ const result1 = FMA(large, small, 1)
66
+ expect(result1).toBeCloseTo(2, 0); // large*small is approximately 1, so result is approximately 2
67
+ expect(FMA(small, small, large)).toBeCloseTo(large, 5); // small*small is negligible
68
+ expect(FMA(large, large, -large * large)).toBeCloseTo(0, 5); // cancellation
69
+ });
70
+
71
+ it('should be equivalent to x * y + z for simple cases', () => {
72
+ const testCases = [
73
+ [1, 2, 3],
74
+ [0.5, 0.25, 0.125],
75
+ [-1, 2, -3],
76
+ [10, 0.1, 5]
77
+ ];
78
+
79
+ testCases.forEach(([x, y, z]) => {
80
+ expect(FMA(x, y, z)).toBeCloseTo(x * y + z, 10);
81
+ });
82
+ });
83
+ });
@@ -0,0 +1,7 @@
1
+ // FMA returns x * y + z, computed with only one rounding.
2
+ // (That is, FMA returns the fused multiply-add of x, y, and z.)
3
+ export function FMA(x: number, y: number, z: number): number {
4
+ // JavaScript doesn't have native FMA, so we use the simple implementation
5
+ // This may not be as precise as a true FMA but is much simpler
6
+ return x * y + z
7
+ }
@@ -0,0 +1,146 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { Frexp, frexp } from './frexp.gs.js';
3
+ import { Inf, NaN as GoNaN, IsNaN } from './bits.gs.js';
4
+
5
+ describe('Frexp', () => {
6
+ it('should break numbers into normalized fraction and exponent', () => {
7
+ // Test basic cases where we can verify the math
8
+ let [frac, exp] = Frexp(8);
9
+ expect(frac).toBeCloseTo(0.5, 10);
10
+ expect(exp).toBe(4); // 8 = 0.5 * 2^4
11
+
12
+ [frac, exp] = Frexp(1);
13
+ expect(frac).toBeCloseTo(0.5, 10);
14
+ expect(exp).toBe(1); // 1 = 0.5 * 2^1
15
+
16
+ [frac, exp] = Frexp(2);
17
+ expect(frac).toBeCloseTo(0.5, 10);
18
+ expect(exp).toBe(2); // 2 = 0.5 * 2^2
19
+
20
+ [frac, exp] = Frexp(4);
21
+ expect(frac).toBeCloseTo(0.5, 10);
22
+ expect(exp).toBe(3); // 4 = 0.5 * 2^3
23
+ });
24
+
25
+ it('should handle fractional numbers', () => {
26
+ let [frac, exp] = Frexp(0.5);
27
+ expect(frac).toBeCloseTo(0.5, 10);
28
+ expect(exp).toBe(0); // 0.5 = 0.5 * 2^0
29
+
30
+ [frac, exp] = Frexp(0.25);
31
+ expect(frac).toBeCloseTo(0.5, 10);
32
+ expect(exp).toBe(-1); // 0.25 = 0.5 * 2^-1
33
+
34
+ [frac, exp] = Frexp(0.125);
35
+ expect(frac).toBeCloseTo(0.5, 10);
36
+ expect(exp).toBe(-2); // 0.125 = 0.5 * 2^-2
37
+ });
38
+
39
+ it('should handle negative numbers', () => {
40
+ let [frac, exp] = Frexp(-8);
41
+ expect(frac).toBeCloseTo(-0.5, 10);
42
+ expect(exp).toBe(4); // -8 = -0.5 * 2^4
43
+
44
+ [frac, exp] = Frexp(-1);
45
+ expect(frac).toBeCloseTo(-0.5, 10);
46
+ expect(exp).toBe(1); // -1 = -0.5 * 2^1
47
+
48
+ [frac, exp] = Frexp(-0.5);
49
+ expect(frac).toBeCloseTo(-0.5, 10);
50
+ expect(exp).toBe(0); // -0.5 = -0.5 * 2^0
51
+ });
52
+
53
+ it('should handle zero values', () => {
54
+ let [frac, exp] = Frexp(0);
55
+ expect(frac).toBe(0);
56
+ expect(exp).toBe(0);
57
+
58
+ [frac, exp] = Frexp(-0);
59
+ expect(frac).toBe(-0);
60
+ expect(exp).toBe(0);
61
+ expect(Object.is(frac, -0)).toBe(true); // Preserve sign of zero
62
+ });
63
+
64
+ it('should handle infinity cases', () => {
65
+ let [frac, exp] = Frexp(Inf(1));
66
+ expect(frac).toBe(Inf(1));
67
+ expect(exp).toBe(0);
68
+
69
+ [frac, exp] = Frexp(Inf(-1));
70
+ expect(frac).toBe(Inf(-1));
71
+ expect(exp).toBe(0);
72
+ });
73
+
74
+ it('should handle NaN cases', () => {
75
+ let [frac, _exp] = Frexp(GoNaN());
76
+ expect(IsNaN(frac)).toBe(true);
77
+ expect(_exp).toBe(0);
78
+ });
79
+
80
+ it('should satisfy the fundamental property f = frac * 2^exp', () => {
81
+ const testValues = [1, 2, 3, 4, 5, 8, 16, 0.5, 0.25, 0.125, 1.5, 3.14159, 100, 1000];
82
+
83
+ testValues.forEach(value => {
84
+ const [frac, exp] = Frexp(value);
85
+ const reconstructed = frac * Math.pow(2, exp);
86
+ expect(reconstructed).toBeCloseTo(value, 10);
87
+ });
88
+
89
+ // Test negative values
90
+ testValues.forEach(value => {
91
+ const [frac, exp] = Frexp(-value);
92
+ const reconstructed = frac * Math.pow(2, exp);
93
+ expect(reconstructed).toBeCloseTo(-value, 10);
94
+ });
95
+ });
96
+
97
+ it('should ensure fraction is in range [0.5, 1) for positive numbers', () => {
98
+ const testValues = [1, 2, 3, 4, 5, 8, 16, 0.5, 0.25, 0.125, 1.5, 3.14159, 100, 1000];
99
+
100
+ testValues.forEach(value => {
101
+ const [frac, _exp] = Frexp(value);
102
+ if (value !== 0) {
103
+ expect(Math.abs(frac)).toBeGreaterThanOrEqual(0.5);
104
+ expect(Math.abs(frac)).toBeLessThan(1);
105
+ }
106
+ });
107
+ });
108
+
109
+ it('should handle very large numbers', () => {
110
+ const large = 1e100;
111
+ const [frac, exp] = Frexp(large);
112
+ expect(Math.abs(frac)).toBeGreaterThanOrEqual(0.5);
113
+ expect(Math.abs(frac)).toBeLessThan(1);
114
+ expect(frac * Math.pow(2, exp)).toBeCloseTo(large, 5);
115
+ });
116
+
117
+ it('should handle very small numbers', () => {
118
+ const small = 1e-100;
119
+ const [frac, exp] = Frexp(small);
120
+ expect(Math.abs(frac)).toBeGreaterThanOrEqual(0.5);
121
+ expect(Math.abs(frac)).toBeLessThan(1);
122
+ expect(frac * Math.pow(2, exp)).toBeCloseTo(small, 110);
123
+ });
124
+ });
125
+
126
+ describe('frexp (lowercase)', () => {
127
+ it('should work identically to Frexp', () => {
128
+ const testValues = [0, 1, 2, 4, 8, 0.5, 0.25, -1, -2, 3.14159];
129
+
130
+ testValues.forEach(value => {
131
+ const [frac1, exp1] = Frexp(value);
132
+ const [frac2, exp2] = frexp(value);
133
+ expect(frac1).toBe(frac2);
134
+ expect(exp1).toBe(exp2);
135
+ });
136
+
137
+ // Test special cases
138
+ expect(frexp(Inf(1))).toEqual(Frexp(Inf(1)));
139
+ expect(frexp(Inf(-1))).toEqual(Frexp(Inf(-1)));
140
+
141
+ const [fracNaN1, expNaN1] = frexp(GoNaN());
142
+ const [fracNaN2, expNaN2] = Frexp(GoNaN());
143
+ expect(IsNaN(fracNaN1)).toBe(IsNaN(fracNaN2));
144
+ expect(expNaN1).toBe(expNaN2);
145
+ });
146
+ });
@@ -0,0 +1,37 @@
1
+ import * as $ from "@goscript/builtin/builtin.js";
2
+ import { IsInf, IsNaN, normalize } from "./bits.gs.js";
3
+
4
+ import { Float64bits, Float64frombits } from "./unsafe.gs.js";
5
+
6
+ // Frexp breaks f into a normalized fraction
7
+ // and an integral power of two.
8
+ // It returns frac and exp satisfying f == frac × 2**exp,
9
+ // with the absolute value of frac in the interval [½, 1).
10
+ //
11
+ // Special cases are:
12
+ //
13
+ // Frexp(±0) = ±0, 0
14
+ // Frexp(±Inf) = ±Inf, 0
15
+ // Frexp(NaN) = NaN, 0
16
+ export function Frexp(f: number): [number, number] {
17
+ return frexp(f)
18
+ }
19
+
20
+ export function frexp(f: number): [number, number] {
21
+ // Handle special cases
22
+ if (f === 0) {
23
+ return [f, 0] // Preserve sign of zero
24
+ }
25
+
26
+ if (!Number.isFinite(f) || Number.isNaN(f)) {
27
+ return [f, 0]
28
+ }
29
+
30
+ // For normal numbers, extract exponent and mantissa
31
+ const absF = Math.abs(f)
32
+ const exp = Math.floor(Math.log2(absF)) + 1
33
+ const frac = f / Math.pow(2, exp)
34
+
35
+ return [frac, exp]
36
+ }
37
+
@@ -0,0 +1,66 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { Gamma } from './gamma.gs.js'
3
+
4
+ describe('Gamma', () => {
5
+ it('should return correct values for positive integers', () => {
6
+ expect(Gamma(1)).toBe(1)
7
+ expect(Gamma(2)).toBe(1)
8
+ expect(Gamma(3)).toBe(2)
9
+ expect(Gamma(4)).toBe(6)
10
+ expect(Gamma(5)).toBe(24)
11
+ })
12
+
13
+ it('should return correct values for half-integers', () => {
14
+ expect(Gamma(0.5)).toBeCloseTo(1.7724538509055159, 14)
15
+ expect(Gamma(1.5)).toBeCloseTo(0.8862269254527579, 14)
16
+ expect(Gamma(2.5)).toBeCloseTo(1.329340388179137, 14)
17
+ })
18
+
19
+ it('should handle negative non-integer values', () => {
20
+ expect(Gamma(-0.5)).toBeCloseTo(-3.5449077018110318, 14)
21
+ expect(Gamma(-1.5)).toBeCloseTo(2.363271801207355, 14)
22
+ expect(Gamma(-2.5)).toBeCloseTo(-0.9453087204829419, 14)
23
+ })
24
+
25
+ it('should handle special values', () => {
26
+ expect(Gamma(0)).toBe(Number.POSITIVE_INFINITY)
27
+ expect(Gamma(Number.POSITIVE_INFINITY)).toBe(Number.POSITIVE_INFINITY)
28
+ expect(Number.isNaN(Gamma(Number.NEGATIVE_INFINITY))).toBe(true)
29
+ expect(Number.isNaN(Gamma(Number.NaN))).toBe(true)
30
+ })
31
+
32
+ it('should return NaN for negative integers', () => {
33
+ expect(Number.isNaN(Gamma(-1))).toBe(true)
34
+ expect(Number.isNaN(Gamma(-2))).toBe(true)
35
+ expect(Number.isNaN(Gamma(-3))).toBe(true)
36
+ expect(Number.isNaN(Gamma(-10))).toBe(true)
37
+ })
38
+
39
+ it('should satisfy the recurrence relation Gamma(x+1) = x * Gamma(x)', () => {
40
+ const testValues = [0.5, 1.5, 2.5, 3.5]
41
+ for (const x of testValues) {
42
+ expect(Gamma(x + 1)).toBeCloseTo(x * Gamma(x), 12)
43
+ }
44
+ })
45
+
46
+ it('should handle very small positive values', () => {
47
+ // Relax tolerance for very small values due to JavaScript precision limits
48
+ expect(Gamma(1e-10)).toBeCloseTo(9999999999.422785, 1)
49
+ expect(Gamma(1e-5)).toBeCloseTo(99999.42279422554, 0)
50
+ })
51
+
52
+ it('should handle large positive values', () => {
53
+ expect(Gamma(10)).toBeCloseTo(362880, 8)
54
+ // Relax tolerance for very large values due to JavaScript precision limits
55
+ expect(Gamma(20)).toBeCloseTo(1.21645100408832e17, 10)
56
+ })
57
+
58
+ it('should satisfy reflection formula for negative values', () => {
59
+ // Gamma(x) * Gamma(1-x) = π / sin(πx) for non-integer x
60
+ const x = 0.3
61
+ const gamma_x = Gamma(x)
62
+ const gamma_1_minus_x = Gamma(1 - x)
63
+ const expected = Math.PI / Math.sin(Math.PI * x)
64
+ expect(gamma_x * gamma_1_minus_x).toBeCloseTo(expected, 10)
65
+ })
66
+ })
@@ -0,0 +1,158 @@
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 { Exp } from "./exp.gs.js";
5
+ import { Floor } from "./floor.gs.js";
6
+ import { Modf } from "./modf.gs.js";
7
+ import { Pow } from "./pow.gs.js";
8
+ import { Signbit } from "./signbit.gs.js";
9
+ import { Sin } from "./sin.gs.js";
10
+
11
+ let _gamP = $.arrayToSlice<number>([1.60119522476751861407e-04, 1.19135147006586384913e-03, 1.04213797561761569935e-02, 4.76367800457137231464e-02, 2.07448227648435975150e-01, 4.94214826801497100753e-01, 9.99999999999999996796e-01])
12
+
13
+ let _gamQ = $.arrayToSlice<number>([-2.31581873324120129819e-05, 5.39605580493303397842e-04, -4.45641913851797240494e-03, 1.18139785222060435552e-02, 3.58236398605498653373e-02, -2.34591795718243348568e-01, 7.14304917030273074085e-02, 1.00000000000000000320e+00])
14
+
15
+ let _gamS = $.arrayToSlice<number>([7.87311395793093628397e-04, -2.29549961613378126380e-04, -2.68132617805781232825e-03, 3.47222221605458667310e-03, 8.33333333333482257126e-02])
16
+
17
+ // Gamma function computed by Stirling's formula.
18
+ // The pair of results must be multiplied together to get the actual answer.
19
+ // The multiplication is left to the caller so that, if careful, the caller can avoid
20
+ // infinity for 172 <= x <= 180.
21
+ // The polynomial is valid for 33 <= x <= 172; larger values are only used
22
+ // in reciprocal and produce denormalized floats. The lower precision there
23
+ // masks any imprecision in the polynomial.
24
+ export function stirling(x: number): [number, number] {
25
+ if (x > 200) {
26
+ return [Inf(1), 1]
27
+ }
28
+ let SqrtTwoPi: number = 2.506628274631000502417
29
+ let MaxStirling: number = 143.01608
30
+ let w = 1 / x
31
+ w = 1 + w * ((((_gamS![0] * w + _gamS![1]) * w + _gamS![2]) * w + _gamS![3]) * w + _gamS![4])
32
+ let y1 = Exp(x)
33
+ let y2 = 1.0
34
+ // avoid Pow() overflow
35
+ if (x > 143.016) {
36
+ // avoid Pow() overflow
37
+ let v = Pow(x, 0.5 * x - 0.25)
38
+ y1 = v
39
+ y2 = v / y1
40
+ } else {
41
+ y1 = Pow(x, x - 0.5) / y1
42
+ }
43
+ return [y1, 2.50663 * w * y2]
44
+ }
45
+
46
+ // Gamma returns the Gamma function of x.
47
+ //
48
+ // Special cases are:
49
+ //
50
+ // Gamma(+Inf) = +Inf
51
+ // Gamma(+0) = +Inf
52
+ // Gamma(-0) = -Inf
53
+ // Gamma(x) = NaN for integer x < 0
54
+ // Gamma(-Inf) = NaN
55
+ // Gamma(NaN) = NaN
56
+ export function Gamma(x: number): number {
57
+ // A001620
58
+ let Euler: number = 0.57721566490153286060651209008240243104215933593992
59
+ // special cases
60
+ switch (true) {
61
+ case isNegInt(x) || IsInf(x, -1) || IsNaN(x):
62
+ return NaN()
63
+ break
64
+ case IsInf(x, 1):
65
+ return Inf(1)
66
+ break
67
+ case x == 0:
68
+ if (Signbit(x)) {
69
+ return Inf(-1)
70
+ }
71
+ return Inf(1)
72
+ break
73
+ }
74
+ let q = Abs(x)
75
+ let p = Floor(q)
76
+
77
+ // Note: x is negative but (checked above) not a negative integer,
78
+ // so x must be small enough to be in range for conversion to int64.
79
+ // If |x| were >= 2⁶³ it would have to be an integer.
80
+ if (q > 33) {
81
+ if (x >= 0) {
82
+ let [y1, y2] = stirling(x)
83
+ return y1 * y2
84
+ }
85
+ // Note: x is negative but (checked above) not a negative integer,
86
+ // so x must be small enough to be in range for conversion to int64.
87
+ // If |x| were >= 2⁶³ it would have to be an integer.
88
+ let signgam = 1
89
+ {
90
+ let ip = (p as number)
91
+ if ((ip & 1) == 0) {
92
+ signgam = -1
93
+ }
94
+ }
95
+ let z = q - p
96
+ if (z > 0.5) {
97
+ p = p + 1
98
+ z = q - p
99
+ }
100
+ z = q * Sin(3.14159 * z)
101
+ if (z == 0) {
102
+ return Inf(signgam)
103
+ }
104
+ let [sq1, sq2] = stirling(q)
105
+ let absz = Abs(z)
106
+ let d = absz * sq1 * sq2
107
+ if (IsInf(d, 0)) {
108
+ z = 3.14159 / absz / sq1 / sq2
109
+ } else {
110
+ z = 3.14159 / d
111
+ }
112
+ return (signgam as number) * z
113
+ }
114
+
115
+ // Reduce argument
116
+ let z = 1.0
117
+ for (; x >= 3; ) {
118
+ x = x - 1
119
+ z = z * x
120
+ }
121
+ for (; x < 0; ) {
122
+ if (x > -1e-09) {
123
+ // unhandled branch statement token: goto
124
+ }
125
+ z = z / x
126
+ x = x + 1
127
+ }
128
+ for (; x < 2; ) {
129
+ if (x < 1e-09) {
130
+ // unhandled branch statement token: goto
131
+ }
132
+ z = z / x
133
+ x = x + 1
134
+ }
135
+
136
+ if (x == 2) {
137
+ return z
138
+ }
139
+
140
+ x = x - 2
141
+ p = (((((x * _gamP![0] + _gamP![1]) * x + _gamP![2]) * x + _gamP![3]) * x + _gamP![4]) * x + _gamP![5]) * x + _gamP![6]
142
+ q = ((((((x * _gamQ![0] + _gamQ![1]) * x + _gamQ![2]) * x + _gamQ![3]) * x + _gamQ![4]) * x + _gamQ![5]) * x + _gamQ![6]) * x + _gamQ![7]
143
+ return z * p / q
144
+
145
+ small: if (x == 0) {
146
+ return Inf(1)
147
+ }
148
+ return z / ((1 + 0.577216 * x) * x)
149
+ }
150
+
151
+ export function isNegInt(x: number): boolean {
152
+ if (x < 0) {
153
+ let [, xf] = Modf(x)
154
+ return xf == 0
155
+ }
156
+ return false
157
+ }
158
+
@@ -0,0 +1,73 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { Hypot, hypot } from './hypot.gs.js';
3
+ import { Inf, NaN as GoNaN, IsNaN, IsInf } from './bits.gs.js';
4
+
5
+ describe('Hypot', () => {
6
+ it('should calculate hypotenuse correctly for basic cases', () => {
7
+ expect(Hypot(3, 4)).toBeCloseTo(5, 10);
8
+ expect(Hypot(5, 12)).toBeCloseTo(13, 10);
9
+ expect(Hypot(8, 15)).toBeCloseTo(17, 10);
10
+ expect(Hypot(1, 1)).toBeCloseTo(Math.sqrt(2), 10);
11
+ });
12
+
13
+ it('should handle zero values', () => {
14
+ expect(Hypot(0, 0)).toBe(0);
15
+ expect(Hypot(0, 5)).toBe(5);
16
+ expect(Hypot(5, 0)).toBe(5);
17
+ expect(Hypot(0, -5)).toBe(5);
18
+ expect(Hypot(-5, 0)).toBe(5);
19
+ });
20
+
21
+ it('should handle negative values', () => {
22
+ expect(Hypot(-3, 4)).toBeCloseTo(5, 10);
23
+ expect(Hypot(3, -4)).toBeCloseTo(5, 10);
24
+ expect(Hypot(-3, -4)).toBeCloseTo(5, 10);
25
+ expect(Hypot(-5, -12)).toBeCloseTo(13, 10);
26
+ });
27
+
28
+ it('should handle infinity cases', () => {
29
+ expect(Hypot(Inf(1), 5)).toBe(Inf(1));
30
+ expect(Hypot(5, Inf(1))).toBe(Inf(1));
31
+ expect(Hypot(Inf(-1), 5)).toBe(Inf(1));
32
+ expect(Hypot(5, Inf(-1))).toBe(Inf(1));
33
+ expect(Hypot(Inf(1), Inf(1))).toBe(Inf(1));
34
+ expect(Hypot(Inf(-1), Inf(-1))).toBe(Inf(1));
35
+ });
36
+
37
+ it('should handle NaN cases', () => {
38
+ expect(IsNaN(Hypot(GoNaN(), 5))).toBe(true);
39
+ expect(IsNaN(Hypot(5, GoNaN()))).toBe(true);
40
+ expect(IsNaN(Hypot(GoNaN(), GoNaN()))).toBe(true);
41
+ });
42
+
43
+ it('should handle very large values without overflow', () => {
44
+ const large = 1e150;
45
+ const result = Hypot(large, large);
46
+ expect(result).toBeCloseTo(large * Math.sqrt(2), 5);
47
+ expect(IsInf(result, 0)).toBe(false);
48
+ });
49
+
50
+ it('should handle very small values without underflow', () => {
51
+ const small = 1e-150;
52
+ const result = Hypot(small, small);
53
+ expect(result).toBeCloseTo(small * Math.sqrt(2), 160);
54
+ expect(result).toBeGreaterThan(0);
55
+ });
56
+
57
+ it('should be commutative', () => {
58
+ expect(Hypot(3, 4)).toBe(Hypot(4, 3));
59
+ expect(Hypot(-3, 4)).toBe(Hypot(4, -3));
60
+ expect(Hypot(1.5, 2.5)).toBe(Hypot(2.5, 1.5));
61
+ });
62
+ });
63
+
64
+ describe('hypot (lowercase)', () => {
65
+ it('should work identically to Hypot', () => {
66
+ expect(hypot(3, 4)).toBe(Hypot(3, 4));
67
+ expect(hypot(5, 12)).toBe(Hypot(5, 12));
68
+ expect(hypot(0, 0)).toBe(Hypot(0, 0));
69
+ expect(hypot(-3, 4)).toBe(Hypot(-3, 4));
70
+ expect(hypot(Inf(1), 5)).toBe(Hypot(Inf(1), 5));
71
+ expect(IsNaN(hypot(GoNaN(), 5))).toBe(IsNaN(Hypot(GoNaN(), 5)));
72
+ });
73
+ });
@@ -0,0 +1,23 @@
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
+ // archHypot import removed - using optimized implementation
5
+ import { Sqrt } from "./sqrt.gs.js";
6
+
7
+ // Hypot returns [Sqrt](p*p + q*q), taking care to avoid
8
+ // unnecessary overflow and underflow.
9
+ //
10
+ // Special cases are:
11
+ //
12
+ // Hypot(±Inf, q) = +Inf
13
+ // Hypot(p, ±Inf) = +Inf
14
+ // Hypot(NaN, q) = NaN
15
+ // Hypot(p, NaN) = NaN
16
+ export function Hypot(p: number, q: number): number {
17
+ return Math.hypot(p, q)
18
+ }
19
+
20
+ export function hypot(p: number, q: number): number {
21
+ return Math.hypot(p, q)
22
+ }
23
+
@@ -0,0 +1,44 @@
1
+ export { Abs } from "./abs.gs.js"
2
+ export { Acosh } from "./acosh.gs.js"
3
+ export { Acos, Asin } from "./asin.gs.js"
4
+ export { Asinh } from "./asinh.gs.js"
5
+ export { Atan } from "./atan.gs.js"
6
+ export { Atan2 } from "./atan2.gs.js"
7
+ export { Atanh } from "./atanh.gs.js"
8
+ export { Inf, IsInf, IsNaN, NaN } from "./bits.gs.js"
9
+ export { Cbrt } from "./cbrt.gs.js"
10
+ export { E, Ln10, Ln2, Log10E, Log2E, MaxFloat32, MaxFloat64, MaxInt, MaxInt16, MaxInt32, MaxInt64, MaxInt8, MaxUint, MaxUint16, MaxUint32, MaxUint64, MaxUint8, MinInt, MinInt16, MinInt32, MinInt64, MinInt8, Phi, Pi, SmallestNonzeroFloat32, SmallestNonzeroFloat64, Sqrt2, SqrtE, SqrtPhi, SqrtPi } from "./const.gs.js"
11
+ export { Copysign } from "./copysign.gs.js"
12
+ export { Dim, Max, Min } from "./dim.gs.js"
13
+ export { Erf, Erfc } from "./erf.gs.js"
14
+ export { Erfcinv, Erfinv } from "./erfinv.gs.js"
15
+ export { Exp, Exp2 } from "./exp.gs.js"
16
+ export { Expm1 } from "./expm1.gs.js"
17
+ export { Ceil, Floor, Round, RoundToEven, Trunc } from "./floor.gs.js"
18
+ export { FMA } from "./fma.gs.js"
19
+ export { Frexp } from "./frexp.gs.js"
20
+ export { Gamma } from "./gamma.gs.js"
21
+ export { Hypot } from "./hypot.gs.js"
22
+ export { J0, Y0 } from "./j0.gs.js"
23
+ export { J1, Y1 } from "./j1.gs.js"
24
+ export { Jn, Yn } from "./jn.gs.js"
25
+ export { Ldexp } from "./ldexp.gs.js"
26
+ export { Lgamma } from "./lgamma.gs.js"
27
+ export { Log } from "./log.gs.js"
28
+ export { Log10, Log2 } from "./log10.gs.js"
29
+ export { Log1p } from "./log1p.gs.js"
30
+ export { Ilogb, Logb } from "./logb.gs.js"
31
+ export { Mod } from "./mod.gs.js"
32
+ export { Modf } from "./modf.gs.js"
33
+ export { Nextafter, Nextafter32 } from "./nextafter.gs.js"
34
+ export { Pow } from "./pow.gs.js"
35
+ export { Pow10 } from "./pow10.gs.js"
36
+ export { Remainder } from "./remainder.gs.js"
37
+ export { Signbit } from "./signbit.gs.js"
38
+ export { Cos, Sin } from "./sin.gs.js"
39
+ export { Sincos } from "./sincos.gs.js"
40
+ export { Cosh, Sinh } from "./sinh.gs.js"
41
+ export { Sqrt } from "./sqrt.gs.js"
42
+ export { Tan } from "./tan.gs.js"
43
+ export { Tanh } from "./tanh.gs.js"
44
+ export { Float32bits, Float32frombits, Float64bits, Float64frombits } from "./unsafe.gs.js"