Skip to content

Commit e1a0f4f

Browse files
authored
Add Math.sumPrecise (#697)
1 parent 428204b commit e1a0f4f

File tree

2 files changed

+60
-1
lines changed

2 files changed

+60
-1
lines changed

quickjs.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43275,6 +43275,64 @@ static JSValue js_math_clz32(JSContext *ctx, JSValue this_val,
4327543275
return js_int32(r);
4327643276
}
4327743277

43278+
static JSValue js_math_sumPrecise(JSContext *ctx, JSValue this_val,
43279+
int argc, JSValue *argv)
43280+
{
43281+
JSValue iter, next, item, ret;
43282+
bf_t a, b;
43283+
BOOL done;
43284+
double d;
43285+
int r;
43286+
43287+
iter = JS_GetIterator(ctx, argv[0], /*async*/FALSE);
43288+
if (JS_IsException(iter))
43289+
return JS_EXCEPTION;
43290+
bf_init(ctx->bf_ctx, &a);
43291+
bf_init(ctx->bf_ctx, &b);
43292+
ret = JS_EXCEPTION;
43293+
next = JS_GetProperty(ctx, iter, JS_ATOM_next);
43294+
if (JS_IsException(next))
43295+
goto fail;
43296+
bf_set_zero(&a, /*is_neg*/TRUE);
43297+
for (;;) {
43298+
item = JS_IteratorNext(ctx, iter, next, 0, NULL, &done);
43299+
if (JS_IsException(item))
43300+
goto fail;
43301+
if (done)
43302+
break; // item == JS_UNDEFINED
43303+
switch (JS_VALUE_GET_TAG(item)) {
43304+
default:
43305+
JS_FreeValue(ctx, item);
43306+
JS_ThrowTypeError(ctx, "not a number");
43307+
goto fail;
43308+
case JS_TAG_INT:
43309+
d = JS_VALUE_GET_INT(item);
43310+
break;
43311+
case JS_TAG_FLOAT64:
43312+
d = JS_VALUE_GET_FLOAT64(item);
43313+
break;
43314+
}
43315+
if (bf_set_float64(&b, d))
43316+
goto oom;
43317+
// Infinity + -Infinity results in BF_ST_INVALID_OP, sets |a| to nan
43318+
if ((r = bf_add(&a, &a, &b, BF_PREC_INF, BF_RNDN)))
43319+
if (r != BF_ST_INVALID_OP)
43320+
goto oom;
43321+
}
43322+
bf_get_float64(&a, &d, BF_RNDN); // return value deliberately ignored
43323+
ret = js_float64(d);
43324+
fail:
43325+
JS_IteratorClose(ctx, iter, JS_IsException(ret));
43326+
JS_FreeValue(ctx, iter);
43327+
JS_FreeValue(ctx, next);
43328+
bf_delete(&a);
43329+
bf_delete(&b);
43330+
return ret;
43331+
oom:
43332+
JS_ThrowOutOfMemory(ctx);
43333+
goto fail;
43334+
}
43335+
4327843336
/* xorshift* random number generator by Marsaglia */
4327943337
static uint64_t xorshift64star(uint64_t *pstate)
4328043338
{
@@ -43376,6 +43434,7 @@ static const JSCFunctionListEntry js_math_funcs[] = {
4337643434
JS_CFUNC_SPECIAL_DEF("fround", 1, f_f, js_math_fround ),
4337743435
JS_CFUNC_DEF("imul", 2, js_math_imul ),
4337843436
JS_CFUNC_DEF("clz32", 1, js_math_clz32 ),
43437+
JS_CFUNC_DEF("sumPrecise", 1, js_math_sumPrecise ),
4337943438
JS_PROP_STRING_DEF("[Symbol.toStringTag]", "Math", JS_PROP_CONFIGURABLE ),
4338043439
JS_PROP_DOUBLE_DEF("E", 2.718281828459045, 0 ),
4338143440
JS_PROP_DOUBLE_DEF("LN10", 2.302585092994046, 0 ),

test262.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ legacy-regexp=skip
144144
let
145145
logical-assignment-operators
146146
Map
147-
Math.sumPrecise=skip
147+
Math.sumPrecise
148148
new.target
149149
numeric-separator-literal
150150
object-rest

0 commit comments

Comments
 (0)