mirror of
https://github.com/DoneJS-Runtime/quickjs-done-nextgen.git
synced 2025-01-09 17:43:15 +00:00
Add Math.sumPrecise (#697)
This commit is contained in:
parent
428204b802
commit
e1a0f4f1cf
2 changed files with 60 additions and 1 deletions
59
quickjs.c
59
quickjs.c
|
@ -43275,6 +43275,64 @@ static JSValue js_math_clz32(JSContext *ctx, JSValue this_val,
|
||||||
return js_int32(r);
|
return js_int32(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static JSValue js_math_sumPrecise(JSContext *ctx, JSValue this_val,
|
||||||
|
int argc, JSValue *argv)
|
||||||
|
{
|
||||||
|
JSValue iter, next, item, ret;
|
||||||
|
bf_t a, b;
|
||||||
|
BOOL done;
|
||||||
|
double d;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
iter = JS_GetIterator(ctx, argv[0], /*async*/FALSE);
|
||||||
|
if (JS_IsException(iter))
|
||||||
|
return JS_EXCEPTION;
|
||||||
|
bf_init(ctx->bf_ctx, &a);
|
||||||
|
bf_init(ctx->bf_ctx, &b);
|
||||||
|
ret = JS_EXCEPTION;
|
||||||
|
next = JS_GetProperty(ctx, iter, JS_ATOM_next);
|
||||||
|
if (JS_IsException(next))
|
||||||
|
goto fail;
|
||||||
|
bf_set_zero(&a, /*is_neg*/TRUE);
|
||||||
|
for (;;) {
|
||||||
|
item = JS_IteratorNext(ctx, iter, next, 0, NULL, &done);
|
||||||
|
if (JS_IsException(item))
|
||||||
|
goto fail;
|
||||||
|
if (done)
|
||||||
|
break; // item == JS_UNDEFINED
|
||||||
|
switch (JS_VALUE_GET_TAG(item)) {
|
||||||
|
default:
|
||||||
|
JS_FreeValue(ctx, item);
|
||||||
|
JS_ThrowTypeError(ctx, "not a number");
|
||||||
|
goto fail;
|
||||||
|
case JS_TAG_INT:
|
||||||
|
d = JS_VALUE_GET_INT(item);
|
||||||
|
break;
|
||||||
|
case JS_TAG_FLOAT64:
|
||||||
|
d = JS_VALUE_GET_FLOAT64(item);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (bf_set_float64(&b, d))
|
||||||
|
goto oom;
|
||||||
|
// Infinity + -Infinity results in BF_ST_INVALID_OP, sets |a| to nan
|
||||||
|
if ((r = bf_add(&a, &a, &b, BF_PREC_INF, BF_RNDN)))
|
||||||
|
if (r != BF_ST_INVALID_OP)
|
||||||
|
goto oom;
|
||||||
|
}
|
||||||
|
bf_get_float64(&a, &d, BF_RNDN); // return value deliberately ignored
|
||||||
|
ret = js_float64(d);
|
||||||
|
fail:
|
||||||
|
JS_IteratorClose(ctx, iter, JS_IsException(ret));
|
||||||
|
JS_FreeValue(ctx, iter);
|
||||||
|
JS_FreeValue(ctx, next);
|
||||||
|
bf_delete(&a);
|
||||||
|
bf_delete(&b);
|
||||||
|
return ret;
|
||||||
|
oom:
|
||||||
|
JS_ThrowOutOfMemory(ctx);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
/* xorshift* random number generator by Marsaglia */
|
/* xorshift* random number generator by Marsaglia */
|
||||||
static uint64_t xorshift64star(uint64_t *pstate)
|
static uint64_t xorshift64star(uint64_t *pstate)
|
||||||
{
|
{
|
||||||
|
@ -43376,6 +43434,7 @@ static const JSCFunctionListEntry js_math_funcs[] = {
|
||||||
JS_CFUNC_SPECIAL_DEF("fround", 1, f_f, js_math_fround ),
|
JS_CFUNC_SPECIAL_DEF("fround", 1, f_f, js_math_fround ),
|
||||||
JS_CFUNC_DEF("imul", 2, js_math_imul ),
|
JS_CFUNC_DEF("imul", 2, js_math_imul ),
|
||||||
JS_CFUNC_DEF("clz32", 1, js_math_clz32 ),
|
JS_CFUNC_DEF("clz32", 1, js_math_clz32 ),
|
||||||
|
JS_CFUNC_DEF("sumPrecise", 1, js_math_sumPrecise ),
|
||||||
JS_PROP_STRING_DEF("[Symbol.toStringTag]", "Math", JS_PROP_CONFIGURABLE ),
|
JS_PROP_STRING_DEF("[Symbol.toStringTag]", "Math", JS_PROP_CONFIGURABLE ),
|
||||||
JS_PROP_DOUBLE_DEF("E", 2.718281828459045, 0 ),
|
JS_PROP_DOUBLE_DEF("E", 2.718281828459045, 0 ),
|
||||||
JS_PROP_DOUBLE_DEF("LN10", 2.302585092994046, 0 ),
|
JS_PROP_DOUBLE_DEF("LN10", 2.302585092994046, 0 ),
|
||||||
|
|
|
@ -144,7 +144,7 @@ legacy-regexp=skip
|
||||||
let
|
let
|
||||||
logical-assignment-operators
|
logical-assignment-operators
|
||||||
Map
|
Map
|
||||||
Math.sumPrecise=skip
|
Math.sumPrecise
|
||||||
new.target
|
new.target
|
||||||
numeric-separator-literal
|
numeric-separator-literal
|
||||||
object-rest
|
object-rest
|
||||||
|
|
Loading…
Reference in a new issue