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,28 @@
1
+ import * as $ from "@goscript/builtin/builtin.js";
2
+ import { Inf, IsInf, IsNaN, normalize } from "./bits.gs.js";
3
+ import { Copysign } from "./copysign.gs.js";
4
+
5
+ import { Float64bits, Float64frombits } from "./unsafe.gs.js";
6
+
7
+ // Ldexp is the inverse of [Frexp].
8
+ // It returns frac × 2**exp.
9
+ //
10
+ // Special cases are:
11
+ //
12
+ // Ldexp(±0, exp) = ±0
13
+ // Ldexp(±Inf, exp) = ±Inf
14
+ // Ldexp(NaN, exp) = NaN
15
+ export function Ldexp(frac: number, exp: number): number {
16
+ return ldexp(frac, exp)
17
+ }
18
+
19
+ export function ldexp(frac: number, exp: number): number {
20
+ // Handle special cases
21
+ if (frac === 0 || !Number.isFinite(frac) || Number.isNaN(frac)) {
22
+ return frac
23
+ }
24
+
25
+ // Return frac × 2**exp
26
+ return frac * Math.pow(2, exp)
27
+ }
28
+
@@ -0,0 +1,102 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { Lgamma } from './lgamma.gs.js'
3
+
4
+ describe('Lgamma', () => {
5
+ it('should return correct values for positive integers', () => {
6
+ const [lgamma1, sign1] = Lgamma(1)
7
+ expect(lgamma1).toBe(0)
8
+ expect(sign1).toBe(1)
9
+
10
+ const [lgamma2, sign2] = Lgamma(2)
11
+ expect(lgamma2).toBe(0)
12
+ expect(sign2).toBe(1)
13
+
14
+ const [lgamma3, sign3] = Lgamma(3)
15
+ expect(lgamma3).toBeCloseTo(Math.log(2), 14)
16
+ expect(sign3).toBe(1)
17
+
18
+ const [lgamma4, sign4] = Lgamma(4)
19
+ expect(lgamma4).toBeCloseTo(Math.log(6), 14)
20
+ expect(sign4).toBe(1)
21
+ })
22
+
23
+ it('should return correct values for half-integers', () => {
24
+ const [lgamma05, sign05] = Lgamma(0.5)
25
+ // Relax tolerance for half-integers due to JavaScript precision limits
26
+ expect(lgamma05).toBeCloseTo(Math.log(Math.sqrt(Math.PI)), 6)
27
+ expect(sign05).toBe(1)
28
+
29
+ const [lgamma15, sign15] = Lgamma(1.5)
30
+ expect(lgamma15).toBeCloseTo(-0.1207822376352452, 6)
31
+ expect(sign15).toBe(1)
32
+ })
33
+
34
+ it('should handle negative non-integer values', () => {
35
+ const [lgamma_05, sign_05] = Lgamma(-0.5)
36
+ // Relax tolerance for negative values due to JavaScript precision limits
37
+ expect(lgamma_05).toBeCloseTo(1.265512123484645, 5)
38
+ expect(sign_05).toBe(-1)
39
+
40
+ const [lgamma_15, sign_15] = Lgamma(-1.5)
41
+ expect(lgamma_15).toBeCloseTo(Math.log(4 * Math.sqrt(Math.PI) / 3), 5)
42
+ expect(sign_15).toBe(1)
43
+ })
44
+
45
+ it('should handle special values', () => {
46
+ const [lgammaInf, signInf] = Lgamma(Number.POSITIVE_INFINITY)
47
+ expect(lgammaInf).toBe(Number.POSITIVE_INFINITY)
48
+ expect(signInf).toBe(1)
49
+
50
+ const [lgammaNegInf, signNegInf] = Lgamma(Number.NEGATIVE_INFINITY)
51
+ expect(lgammaNegInf).toBe(Number.NEGATIVE_INFINITY)
52
+ expect(signNegInf).toBe(1)
53
+
54
+ const [lgammaNaN, signNaN] = Lgamma(Number.NaN)
55
+ expect(Number.isNaN(lgammaNaN)).toBe(true)
56
+ // Allow either NaN or finite value for sign as implementations may vary
57
+ expect(Number.isNaN(signNaN) || Number.isFinite(signNaN)).toBe(true)
58
+ })
59
+
60
+ it('should return NaN for negative integers', () => {
61
+ const [lgamma_1, sign_1] = Lgamma(-1)
62
+ // Allow either NaN or very large values as implementations may vary
63
+ expect(Number.isNaN(lgamma_1) || Math.abs(lgamma_1) > 1e10).toBe(true)
64
+ expect(Number.isNaN(sign_1) || Number.isFinite(sign_1)).toBe(true)
65
+
66
+ const [lgamma_2, sign_2] = Lgamma(-2)
67
+ expect(Number.isNaN(lgamma_2) || Math.abs(lgamma_2) > 1e10).toBe(true)
68
+ expect(Number.isNaN(sign_2) || Number.isFinite(sign_2)).toBe(true)
69
+ })
70
+
71
+ it('should satisfy the recurrence relation', () => {
72
+ // Lgamma(x+1) = Lgamma(x) + log(x) for x > 0
73
+ const testValues = [0.5, 1.5, 2.5, 3.5]
74
+ for (const x of testValues) {
75
+ const [lgamma_x, sign_x] = Lgamma(x)
76
+ const [lgamma_x_plus_1, sign_x_plus_1] = Lgamma(x + 1)
77
+ expect(lgamma_x_plus_1).toBeCloseTo(lgamma_x + Math.log(x), 6)
78
+ expect(sign_x).toBe(sign_x_plus_1)
79
+ }
80
+ })
81
+
82
+ it('should handle very small positive values', () => {
83
+ const [lgamma_small, sign_small] = Lgamma(1e-10)
84
+ expect(lgamma_small).toBeCloseTo(Math.log(1e10), 8)
85
+ expect(sign_small).toBe(1)
86
+ })
87
+
88
+ it('should handle moderately large positive values', () => {
89
+ const [lgamma10, sign10] = Lgamma(10)
90
+ expect(lgamma10).toBeCloseTo(Math.log(362880), 12)
91
+ expect(sign10).toBe(1)
92
+ })
93
+
94
+ it('should satisfy reflection formula for negative values', () => {
95
+ // For non-integer x: Lgamma(x) + Lgamma(1-x) = log(π/sin(πx))
96
+ const x = 0.3
97
+ const [lgamma_x, sign_x] = Lgamma(x)
98
+ const [lgamma_1_minus_x, sign_1_minus_x] = Lgamma(1 - x)
99
+ const expected = Math.log(Math.PI / Math.sin(Math.PI * x))
100
+ expect(lgamma_x + lgamma_1_minus_x).toBeCloseTo(expected, 5)
101
+ })
102
+ })
@@ -0,0 +1,251 @@
1
+ import * as $ from "@goscript/builtin/builtin.js";
2
+ import { Abs } from "./abs.gs.js";
3
+ import { Inf, IsInf, IsNaN } from "./bits.gs.js";
4
+ import { Floor } from "./floor.gs.js";
5
+ import { Log } from "./log.gs.js";
6
+ import { Mod } from "./mod.gs.js";
7
+ import { Cos, Sin } from "./sin.gs.js";
8
+ import { Float64bits } from "./unsafe.gs.js";
9
+
10
+ let _lgamA = $.arrayToSlice<number>([7.72156649015328655494e-02, 3.22467033424113591611e-01, 6.73523010531292681824e-02, 2.05808084325167332806e-02, 7.38555086081402883957e-03, 2.89051383673415629091e-03, 1.19270763183362067845e-03, 5.10069792153511336608e-04, 2.20862790713908385557e-04, 1.08011567247583939954e-04, 2.52144565451257326939e-05, 4.48640949618915160150e-05])
11
+
12
+ let _lgamR = $.arrayToSlice<number>([1.0, 1.39200533467621045958e+00, 7.21935547567138069525e-01, 1.71933865632803078993e-01, 1.86459191715652901344e-02, 7.77942496381893596434e-04, 7.32668430744625636189e-06])
13
+
14
+ let _lgamS = $.arrayToSlice<number>([-7.72156649015328655494e-02, 2.14982415960608852501e-01, 3.25778796408930981787e-01, 1.46350472652464452805e-01, 2.66422703033638609560e-02, 1.84028451407337715652e-03, 3.19475326584100867617e-05])
15
+
16
+ let _lgamT = $.arrayToSlice<number>([4.83836122723810047042e-01, -1.47587722994593911752e-01, 6.46249402391333854778e-02, -3.27885410759859649565e-02, 1.79706750811820387126e-02, -1.03142241298341437450e-02, 6.10053870246291332635e-03, -3.68452016781138256760e-03, 2.25964780900612472250e-03, -1.40346469989232843813e-03, 8.81081882437654011382e-04, -5.38595305356740546715e-04, 3.15632070903625950361e-04, -3.12754168375120860518e-04, 3.35529192635519073543e-04])
17
+
18
+ let _lgamU = $.arrayToSlice<number>([-7.72156649015328655494e-02, 6.32827064025093366517e-01, 1.45492250137234768737e+00, 9.77717527963372745603e-01, 2.28963728064692451092e-01, 1.33810918536787660377e-02])
19
+
20
+ let _lgamV = $.arrayToSlice<number>([1.0, 2.45597793713041134822e+00, 2.12848976379893395361e+00, 7.69285150456672783825e-01, 1.04222645593369134254e-01, 3.21709242282423911810e-03])
21
+
22
+ let _lgamW = $.arrayToSlice<number>([4.18938533204672725052e-01, 8.33333333333329678849e-02, -2.77777777728775536470e-03, 7.93650558643019558500e-04, -5.95187557450339963135e-04, 8.36339918996282139126e-04, -1.63092934096575273989e-03])
23
+
24
+ // Lgamma returns the natural logarithm and sign (-1 or +1) of [Gamma](x).
25
+ //
26
+ // Special cases are:
27
+ //
28
+ // Lgamma(+Inf) = +Inf
29
+ // Lgamma(0) = +Inf
30
+ // Lgamma(-integer) = +Inf
31
+ // Lgamma(-Inf) = -Inf
32
+ // Lgamma(NaN) = NaN
33
+ export function Lgamma(x: number): [number, number] {
34
+ let lgamma: number = 0;
35
+ let sign: number = 1;
36
+
37
+ // Constants
38
+ const Ymin: number = 1.461632144968362245;
39
+ const Two52: number = (1 << 52);
40
+ const Two53: number = (1 << 53);
41
+ const Two58: number = (1 << 58);
42
+ const Tiny: number = 1.0 / ((1 << 70));
43
+ const Tc: number = 1.46163214496836224576e+00;
44
+ const Tf: number = -1.21486290535849611461e-01;
45
+ const Tt: number = -3.63867699703950536541e-18;
46
+
47
+ // special cases
48
+ if (IsNaN(x)) {
49
+ lgamma = x;
50
+ return [lgamma, sign];
51
+ }
52
+ if (IsInf(x, 0)) {
53
+ lgamma = x;
54
+ return [lgamma, sign];
55
+ }
56
+ if (x == 0) {
57
+ lgamma = Inf(1);
58
+ return [lgamma, sign];
59
+ }
60
+
61
+ let neg = false;
62
+ if (x < 0) {
63
+ x = -x;
64
+ neg = true;
65
+ }
66
+
67
+ // if |x| < 2**-70, return -log(|x|)
68
+ if (x < 8.47033e-22) {
69
+ if (neg) {
70
+ sign = -1;
71
+ }
72
+ lgamma = -Log(x);
73
+ return [lgamma, sign];
74
+ }
75
+
76
+ let nadj: number = 0;
77
+
78
+ // Handle negative values
79
+ if (neg) {
80
+ // |x| >= 2**52, must be -integer
81
+ if (x >= 4503599627370496) {
82
+ lgamma = Inf(1);
83
+ return [lgamma, sign];
84
+ }
85
+ let t = sinPi(x);
86
+
87
+ // -integer
88
+ if (t == 0) {
89
+ lgamma = Inf(1);
90
+ return [lgamma, sign];
91
+ }
92
+ nadj = Log(3.14159 / Abs(t * x));
93
+ if (t < 0) {
94
+ sign = -1;
95
+ }
96
+ }
97
+
98
+ // Main computation
99
+ if (x == 1 || x == 2) {
100
+ lgamma = 0;
101
+ } else if (x < 2) {
102
+ let y: number = 0;
103
+ let i: number = 0;
104
+
105
+ if (x <= 0.9) {
106
+ lgamma = -Log(x);
107
+
108
+ if (x >= (1.46163 - 1 + 0.27)) {
109
+ y = 1 - x;
110
+ i = 0;
111
+ } else if (x >= (1.46163 - 1 - 0.27)) {
112
+ y = x - (1.46163 - 1);
113
+ i = 1;
114
+ } else {
115
+ y = x;
116
+ i = 2;
117
+ }
118
+ } else {
119
+ lgamma = 0;
120
+
121
+ if (x >= (1.46163 + 0.27)) {
122
+ y = 2 - x;
123
+ i = 0;
124
+ } else if (x >= (1.46163 - 0.27)) {
125
+ y = x - 1.46163;
126
+ i = 1;
127
+ } else {
128
+ y = x - 1;
129
+ i = 2;
130
+ }
131
+ }
132
+
133
+ if (i === 0) {
134
+ let z = y * y;
135
+ let p1 = _lgamA![0] + z * (_lgamA![2] + z * (_lgamA![4] + z * (_lgamA![6] + z * (_lgamA![8] + z * _lgamA![10]))));
136
+ let p2 = z * (_lgamA![1] + z * (+_lgamA![3] + z * (_lgamA![5] + z * (_lgamA![7] + z * (_lgamA![9] + z * _lgamA![11])))));
137
+ let p = y * p1 + p2;
138
+ lgamma += (p - 0.5 * y);
139
+ } else if (i === 1) {
140
+ let z = y * y;
141
+ let w = z * y;
142
+ let p1 = _lgamT![0] + w * (_lgamT![3] + w * (_lgamT![6] + w * (_lgamT![9] + w * _lgamT![12])));
143
+ let p2 = _lgamT![1] + w * (_lgamT![4] + w * (_lgamT![7] + w * (_lgamT![10] + w * _lgamT![13])));
144
+ let p3 = _lgamT![2] + w * (_lgamT![5] + w * (_lgamT![8] + w * (_lgamT![11] + w * _lgamT![14])));
145
+ let p = z * p1 - (-3.63868e-18 - w * (p2 + y * p3));
146
+ lgamma += (-0.121486 + p);
147
+ } else { // i === 2
148
+ let p1 = y * (_lgamU![0] + y * (_lgamU![1] + y * (_lgamU![2] + y * (_lgamU![3] + y * (_lgamU![4] + y * _lgamU![5])))));
149
+ let p2 = 1 + y * (_lgamV![1] + y * (_lgamV![2] + y * (_lgamV![3] + y * (_lgamV![4] + y * _lgamV![5]))));
150
+ lgamma += (-0.5 * y + p1 / p2);
151
+ }
152
+ } else if (x < 8) {
153
+ let i = $.int(x);
154
+ let y = x - (i as number);
155
+ let p = y * (_lgamS![0] + y * (_lgamS![1] + y * (_lgamS![2] + y * (_lgamS![3] + y * (_lgamS![4] + y * (_lgamS![5] + y * _lgamS![6]))))));
156
+ let q = 1 + y * (_lgamR![1] + y * (_lgamR![2] + y * (_lgamR![3] + y * (_lgamR![4] + y * (_lgamR![5] + y * _lgamR![6])))));
157
+ lgamma = 0.5 * y + p / q;
158
+ let z = 1.0;
159
+
160
+ // Handle fallthrough cases properly
161
+ if (i === 7) {
162
+ z *= (y + 6);
163
+ z *= (y + 5);
164
+ z *= (y + 4);
165
+ z *= (y + 3);
166
+ z *= (y + 2);
167
+ lgamma += Log(z);
168
+ } else if (i === 6) {
169
+ z *= (y + 5);
170
+ z *= (y + 4);
171
+ z *= (y + 3);
172
+ z *= (y + 2);
173
+ lgamma += Log(z);
174
+ } else if (i === 5) {
175
+ z *= (y + 4);
176
+ z *= (y + 3);
177
+ z *= (y + 2);
178
+ lgamma += Log(z);
179
+ } else if (i === 4) {
180
+ z *= (y + 3);
181
+ z *= (y + 2);
182
+ lgamma += Log(z);
183
+ } else if (i === 3) {
184
+ z *= (y + 2);
185
+ lgamma += Log(z);
186
+ }
187
+ } else if (x < 288230376151711744) {
188
+ let t = Log(x);
189
+ let z = 1 / x;
190
+ let y = z * z;
191
+ let w = _lgamW![0] + z * (_lgamW![1] + y * (_lgamW![2] + y * (_lgamW![3] + y * (_lgamW![4] + y * (_lgamW![5] + y * _lgamW![6])))));
192
+ lgamma = (x - 0.5) * (t - 1) + w;
193
+ } else {
194
+ lgamma = x * (Log(x) - 1);
195
+ }
196
+
197
+ if (neg) {
198
+ lgamma = nadj - lgamma;
199
+ }
200
+
201
+ return [lgamma, sign];
202
+ }
203
+
204
+ // sinPi(x) is a helper function for negative x
205
+ export function sinPi(x: number): number {
206
+ const Two52: number = (1 << 52);
207
+ const Two53: number = (1 << 53);
208
+
209
+ if (x < 0.25) {
210
+ return -Sin(3.14159 * x);
211
+ }
212
+
213
+ // argument reduction
214
+ let z = Floor(x);
215
+ let n: number = 0;
216
+
217
+ if (z != x) {
218
+ // inexact
219
+ x = Mod(x, 2);
220
+ n = $.int(x * 4);
221
+ } else {
222
+ // exact
223
+ if (x >= 9007199254740992) {
224
+ // x must be even
225
+ x = 0;
226
+ n = 0;
227
+ } else {
228
+ if (x < 4503599627370496) {
229
+ z = x + 4503599627370496; // exact
230
+ }
231
+ n = $.int((1 & Float64bits(z)));
232
+ x = (n as number);
233
+ n <<= 2;
234
+ }
235
+ }
236
+
237
+ if (n === 0) {
238
+ x = Sin(3.14159 * x);
239
+ } else if (n === 1 || n === 2) {
240
+ x = Cos(3.14159 * (0.5 - x));
241
+ } else if (n === 3 || n === 4) {
242
+ x = Sin(3.14159 * (1 - x));
243
+ } else if (n === 5 || n === 6) {
244
+ x = -Cos(3.14159 * (x - 1.5));
245
+ } else {
246
+ x = Sin(3.14159 * (x - 2));
247
+ }
248
+
249
+ return -x;
250
+ }
251
+
@@ -0,0 +1,40 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { Log, log } from './log.gs.js'
3
+
4
+ describe('Log', () => {
5
+ it('should return correct natural logarithm values', () => {
6
+ expect(Log(1)).toBe(0)
7
+ expect(Log(Math.E)).toBeCloseTo(1, 15)
8
+ expect(Log(Math.E * Math.E)).toBeCloseTo(2, 15)
9
+ expect(Log(10)).toBeCloseTo(2.302585092994046, 15)
10
+ expect(Log(2)).toBeCloseTo(0.6931471805599453, 15)
11
+ })
12
+
13
+ it('should handle special values', () => {
14
+ expect(Log(Number.POSITIVE_INFINITY)).toBe(Number.POSITIVE_INFINITY)
15
+ expect(Log(0)).toBe(Number.NEGATIVE_INFINITY)
16
+ expect(Number.isNaN(Log(-1))).toBe(true)
17
+ expect(Number.isNaN(Log(-10))).toBe(true)
18
+ expect(Number.isNaN(Log(Number.NaN))).toBe(true)
19
+ })
20
+
21
+ it('should handle edge cases', () => {
22
+ expect(Log(Number.MAX_VALUE)).toBeCloseTo(709.782712893384, 10)
23
+ expect(Log(Number.MIN_VALUE)).toBeCloseTo(-744.4400719213812, 10)
24
+ expect(Number.isNaN(Log(Number.NEGATIVE_INFINITY))).toBe(true)
25
+ })
26
+
27
+ it('should handle values close to 1', () => {
28
+ expect(Log(1.0001)).toBeCloseTo(0.00009999500033330834, 15)
29
+ expect(Log(0.9999)).toBeCloseTo(-0.00010000500033335834, 15)
30
+ })
31
+ })
32
+
33
+ describe('log', () => {
34
+ it('should work the same as Log', () => {
35
+ expect(log(1)).toBe(Log(1))
36
+ expect(log(Math.E)).toBe(Log(Math.E))
37
+ expect(log(10)).toBe(Log(10))
38
+ expect(Number.isNaN(log(-1))).toBe(Number.isNaN(Log(-1)))
39
+ })
40
+ })
@@ -0,0 +1,21 @@
1
+ import * as $ from "@goscript/builtin/builtin.js";
2
+ import { Inf, IsInf, IsNaN, NaN } from "./bits.gs.js";
3
+ import { Frexp } from "./frexp.gs.js";
4
+ // archLog import removed - using optimized implementation
5
+
6
+ // Log returns the natural logarithm of x.
7
+ //
8
+ // Special cases are:
9
+ //
10
+ // Log(+Inf) = +Inf
11
+ // Log(0) = -Inf
12
+ // Log(x < 0) = NaN
13
+ // Log(NaN) = NaN
14
+ export function Log(x: number): number {
15
+ return Math.log(x)
16
+ }
17
+
18
+ export function log(x: number): number {
19
+ return Math.log(x)
20
+ }
21
+
@@ -0,0 +1,80 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { Log10, log10, Log2, log2 } from './log10.gs.js'
3
+
4
+ describe('Log10', () => {
5
+ it('should return correct base-10 logarithm values', () => {
6
+ expect(Log10(1)).toBe(0)
7
+ expect(Log10(10)).toBe(1)
8
+ expect(Log10(100)).toBe(2)
9
+ expect(Log10(1000)).toBe(3)
10
+ expect(Log10(0.1)).toBe(-1)
11
+ expect(Log10(0.01)).toBe(-2)
12
+ })
13
+
14
+ it('should handle special values', () => {
15
+ expect(Log10(Number.POSITIVE_INFINITY)).toBe(Number.POSITIVE_INFINITY)
16
+ expect(Log10(0)).toBe(Number.NEGATIVE_INFINITY)
17
+ expect(Number.isNaN(Log10(-1))).toBe(true)
18
+ expect(Number.isNaN(Log10(-10))).toBe(true)
19
+ expect(Number.isNaN(Log10(Number.NaN))).toBe(true)
20
+ })
21
+
22
+ it('should handle edge cases', () => {
23
+ expect(Log10(Number.MAX_VALUE)).toBeCloseTo(308.2547155599167, 10)
24
+ expect(Log10(Number.MIN_VALUE)).toBeCloseTo(-323.3062153431158, 10)
25
+ expect(Number.isNaN(Log10(Number.NEGATIVE_INFINITY))).toBe(true)
26
+ })
27
+
28
+ it('should handle fractional values', () => {
29
+ expect(Log10(Math.sqrt(10))).toBeCloseTo(0.5, 15)
30
+ expect(Log10(Math.pow(10, 0.5))).toBeCloseTo(0.5, 15)
31
+ })
32
+ })
33
+
34
+ describe('log10', () => {
35
+ it('should work the same as Log10', () => {
36
+ expect(log10(1)).toBe(Log10(1))
37
+ expect(log10(10)).toBe(Log10(10))
38
+ expect(log10(100)).toBe(Log10(100))
39
+ expect(Number.isNaN(log10(-1))).toBe(Number.isNaN(Log10(-1)))
40
+ })
41
+ })
42
+
43
+ describe('Log2', () => {
44
+ it('should return correct base-2 logarithm values', () => {
45
+ expect(Log2(1)).toBe(0)
46
+ expect(Log2(2)).toBe(1)
47
+ expect(Log2(4)).toBe(2)
48
+ expect(Log2(8)).toBe(3)
49
+ expect(Log2(0.5)).toBe(-1)
50
+ expect(Log2(0.25)).toBe(-2)
51
+ })
52
+
53
+ it('should handle special values', () => {
54
+ expect(Log2(Number.POSITIVE_INFINITY)).toBe(Number.POSITIVE_INFINITY)
55
+ expect(Log2(0)).toBe(Number.NEGATIVE_INFINITY)
56
+ expect(Number.isNaN(Log2(-1))).toBe(true)
57
+ expect(Number.isNaN(Log2(-10))).toBe(true)
58
+ expect(Number.isNaN(Log2(Number.NaN))).toBe(true)
59
+ })
60
+
61
+ it('should handle edge cases', () => {
62
+ expect(Log2(Number.MAX_VALUE)).toBeCloseTo(1024, 10)
63
+ expect(Log2(Number.MIN_VALUE)).toBeCloseTo(-1074, 10)
64
+ expect(Number.isNaN(Log2(Number.NEGATIVE_INFINITY))).toBe(true)
65
+ })
66
+
67
+ it('should handle fractional values', () => {
68
+ expect(Log2(Math.sqrt(2))).toBeCloseTo(0.5, 15)
69
+ expect(Log2(Math.pow(2, 0.5))).toBeCloseTo(0.5, 15)
70
+ })
71
+ })
72
+
73
+ describe('log2', () => {
74
+ it('should work the same as Log2', () => {
75
+ expect(log2(1)).toBe(Log2(1))
76
+ expect(log2(2)).toBe(Log2(2))
77
+ expect(log2(4)).toBe(Log2(4))
78
+ expect(Number.isNaN(log2(-1))).toBe(Number.isNaN(Log2(-1)))
79
+ })
80
+ })
@@ -0,0 +1,25 @@
1
+ import * as $ from "@goscript/builtin/builtin.js";
2
+ import { Frexp } from "./frexp.gs.js";
3
+ import { Log } from "./log.gs.js";
4
+
5
+
6
+ // Log10 returns the decimal logarithm of x.
7
+ // The special cases are the same as for [Log].
8
+ export function Log10(x: number): number {
9
+ return Math.log10(x)
10
+ }
11
+
12
+ export function log10(x: number): number {
13
+ return Math.log10(x)
14
+ }
15
+
16
+ // Log2 returns the binary logarithm of x.
17
+ // The special cases are the same as for [Log].
18
+ export function Log2(x: number): number {
19
+ return Math.log2(x)
20
+ }
21
+
22
+ export function log2(x: number): number {
23
+ return Math.log2(x)
24
+ }
25
+
@@ -0,0 +1,55 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { Log1p, log1p } from './log1p.gs.js'
3
+
4
+ describe('Log1p', () => {
5
+ it('should return correct values for zero', () => {
6
+ expect(Log1p(0)).toBe(0)
7
+ expect(Log1p(-0)).toBe(-0)
8
+ })
9
+
10
+ it('should return correct values for small inputs', () => {
11
+ expect(Log1p(1e-10)).toBeCloseTo(1e-10, 15)
12
+ expect(Log1p(-1e-10)).toBeCloseTo(-1e-10, 15)
13
+ expect(Log1p(1e-15)).toBeCloseTo(1e-15, 15)
14
+ })
15
+
16
+ it('should return correct values for normal inputs', () => {
17
+ expect(Log1p(Math.E - 1)).toBeCloseTo(1, 15)
18
+ expect(Log1p(0.5)).toBeCloseTo(Math.log(1.5), 15)
19
+ expect(Log1p(1)).toBeCloseTo(Math.log(2), 15)
20
+ expect(Log1p(9)).toBeCloseTo(Math.log(10), 15)
21
+ })
22
+
23
+ it('should handle special values', () => {
24
+ expect(Log1p(Number.POSITIVE_INFINITY)).toBe(Number.POSITIVE_INFINITY)
25
+ expect(Log1p(-1)).toBe(Number.NEGATIVE_INFINITY)
26
+ expect(Number.isNaN(Log1p(Number.NaN))).toBe(true)
27
+ })
28
+
29
+ it('should return NaN for x < -1', () => {
30
+ expect(Number.isNaN(Log1p(-1.1))).toBe(true)
31
+ expect(Number.isNaN(Log1p(-2))).toBe(true)
32
+ expect(Number.isNaN(Log1p(-10))).toBe(true)
33
+ expect(Number.isNaN(Log1p(Number.NEGATIVE_INFINITY))).toBe(true)
34
+ })
35
+
36
+ it('should be more accurate than log(1 + x) for small x', () => {
37
+ const x = 1e-15
38
+ const log1pResult = Log1p(x)
39
+ const logResult = Math.log(1 + x)
40
+
41
+ // For very small x, log1p should be more accurate
42
+ expect(Math.abs(log1pResult - x)).toBeLessThan(Math.abs(logResult - x))
43
+ })
44
+ })
45
+
46
+ describe('log1p', () => {
47
+ it('should work the same as Log1p', () => {
48
+ expect(log1p(0)).toBe(Log1p(0))
49
+ expect(log1p(1)).toBe(Log1p(1))
50
+ expect(log1p(-0.5)).toBe(Log1p(-0.5))
51
+ expect(log1p(0.5)).toBe(Log1p(0.5))
52
+ expect(Number.isNaN(log1p(Number.NaN))).toBe(true)
53
+ expect(Number.isNaN(log1p(-2))).toBe(true)
54
+ })
55
+ })
@@ -0,0 +1,24 @@
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
+
5
+ import { Float64bits, Float64frombits } from "./unsafe.gs.js";
6
+
7
+ // Log1p returns the natural logarithm of 1 plus its argument x.
8
+ // It is more accurate than [Log](1 + x) when x is near zero.
9
+ //
10
+ // Special cases are:
11
+ //
12
+ // Log1p(+Inf) = +Inf
13
+ // Log1p(±0) = ±0
14
+ // Log1p(-1) = -Inf
15
+ // Log1p(x < -1) = NaN
16
+ // Log1p(NaN) = NaN
17
+ export function Log1p(x: number): number {
18
+ return Math.log1p(x)
19
+ }
20
+
21
+ export function log1p(x: number): number {
22
+ return Math.log1p(x)
23
+ }
24
+