mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-26 03:35:33 +00:00
bug 1471134
- Part 1: Define methods for basic BigInt arithmetic. r=Waldo
This commit is contained in:
parent
ad48d9c804
commit
e7f485bfdb
@ -652,6 +652,7 @@ MSG_DEF(JSMSG_RESPONSE_ALREADY_CONSUMED, 0, JSEXN_TYPEERR, "Res
|
||||
// BigInt
|
||||
MSG_DEF(JSMSG_BIGINT_TO_NUMBER, 0, JSEXN_TYPEERR, "can't convert BigInt to number")
|
||||
MSG_DEF(JSMSG_NUMBER_TO_BIGINT, 0, JSEXN_RANGEERR, "can't convert non-finite number to BigInt")
|
||||
MSG_DEF(JSMSG_BIGINT_TOO_LARGE, 0, JSEXN_RANGEERR, "BigInt is too large to allocate")
|
||||
MSG_DEF(JSMSG_BIGINT_DIVISION_BY_ZERO, 0, JSEXN_RANGEERR, "BigInt division by zero")
|
||||
MSG_DEF(JSMSG_BIGINT_NEGATIVE_EXPONENT, 0, JSEXN_RANGEERR, "BigInt negative exponent")
|
||||
MSG_DEF(JSMSG_BIGINT_INVALID_SYNTAX, 0, JSEXN_SYNTAXERR, "invalid BigInt syntax")
|
||||
|
@ -171,6 +171,116 @@ BigInt::copy(JSContext* cx, HandleBigInt x)
|
||||
return bi;
|
||||
}
|
||||
|
||||
// BigInt proposal section 1.1.7
|
||||
BigInt*
|
||||
BigInt::add(JSContext* cx, HandleBigInt x, HandleBigInt y)
|
||||
{
|
||||
BigInt* z = create(cx);
|
||||
if (!z)
|
||||
return nullptr;
|
||||
mpz_add(z->num_, x->num_, y->num_);
|
||||
return z;
|
||||
}
|
||||
|
||||
// BigInt proposal section 1.1.8
|
||||
BigInt*
|
||||
BigInt::sub(JSContext* cx, HandleBigInt x, HandleBigInt y)
|
||||
{
|
||||
BigInt* z = create(cx);
|
||||
if (!z)
|
||||
return nullptr;
|
||||
mpz_sub(z->num_, x->num_, y->num_);
|
||||
return z;
|
||||
}
|
||||
|
||||
// BigInt proposal section 1.1.4
|
||||
BigInt*
|
||||
BigInt::mul(JSContext* cx, HandleBigInt x, HandleBigInt y)
|
||||
{
|
||||
BigInt* z = create(cx);
|
||||
if (!z)
|
||||
return nullptr;
|
||||
mpz_mul(z->num_, x->num_, y->num_);
|
||||
return z;
|
||||
}
|
||||
|
||||
// BigInt proposal section 1.1.5
|
||||
BigInt*
|
||||
BigInt::div(JSContext* cx, HandleBigInt x, HandleBigInt y)
|
||||
{
|
||||
// Step 1.
|
||||
if (mpz_size(y->num_) == 0) {
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
|
||||
JSMSG_BIGINT_DIVISION_BY_ZERO);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Steps 2-3.
|
||||
BigInt* z = create(cx);
|
||||
if (!z)
|
||||
return nullptr;
|
||||
mpz_tdiv_q(z->num_, x->num_, y->num_);
|
||||
return z;
|
||||
}
|
||||
|
||||
// BigInt proposal section 1.1.6
|
||||
BigInt*
|
||||
BigInt::mod(JSContext* cx, HandleBigInt x, HandleBigInt y)
|
||||
{
|
||||
// Step 1.
|
||||
if (mpz_size(y->num_) == 0) {
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
|
||||
JSMSG_BIGINT_DIVISION_BY_ZERO);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Steps 2-4.
|
||||
BigInt* z = create(cx);
|
||||
if (!z)
|
||||
return nullptr;
|
||||
mpz_tdiv_r(z->num_, x->num_, y->num_);
|
||||
return z;
|
||||
}
|
||||
|
||||
// BigInt proposal section 1.1.3
|
||||
BigInt*
|
||||
BigInt::pow(JSContext* cx, HandleBigInt x, HandleBigInt y)
|
||||
{
|
||||
// Step 1.
|
||||
if (mpz_sgn(y->num_) < 0) {
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
|
||||
JSMSG_BIGINT_NEGATIVE_EXPONENT);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Throw a RangeError if the exponent is too large.
|
||||
if (!mpz_fits_uint_p(y->num_)) {
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
|
||||
JSMSG_BIGINT_TOO_LARGE);
|
||||
return nullptr;
|
||||
}
|
||||
unsigned long int power = mpz_get_ui(y->num_);
|
||||
|
||||
// Steps 2-3.
|
||||
BigInt* z = create(cx);
|
||||
if (!z)
|
||||
return nullptr;
|
||||
|
||||
mpz_pow_ui(z->num_, x->num_, power);
|
||||
return z;
|
||||
}
|
||||
|
||||
// BigInt proposal section 1.1.1
|
||||
BigInt*
|
||||
BigInt::neg(JSContext* cx, HandleBigInt x)
|
||||
{
|
||||
BigInt* res = create(cx);
|
||||
if (!res)
|
||||
return nullptr;
|
||||
mpz_neg(res->num_, x->num_);
|
||||
return res;
|
||||
}
|
||||
|
||||
// BigInt proposal section 7.3
|
||||
BigInt*
|
||||
js::ToBigInt(JSContext* cx, HandleValue val)
|
||||
|
@ -73,6 +73,13 @@ class BigInt final : public js::gc::TenuredCell
|
||||
static void init();
|
||||
|
||||
static BigInt* copy(JSContext* cx, Handle<BigInt*> x);
|
||||
static BigInt* add(JSContext* cx, Handle<BigInt*> x, Handle<BigInt*> y);
|
||||
static BigInt* sub(JSContext* cx, Handle<BigInt*> x, Handle<BigInt*> y);
|
||||
static BigInt* mul(JSContext* cx, Handle<BigInt*> x, Handle<BigInt*> y);
|
||||
static BigInt* div(JSContext* cx, Handle<BigInt*> x, Handle<BigInt*> y);
|
||||
static BigInt* mod(JSContext* cx, Handle<BigInt*> x, Handle<BigInt*> y);
|
||||
static BigInt* pow(JSContext* cx, Handle<BigInt*> x, Handle<BigInt*> y);
|
||||
static BigInt* neg(JSContext* cx, Handle<BigInt*> x);
|
||||
|
||||
static double numberValue(BigInt* x);
|
||||
static JSLinearString* toString(JSContext* cx, BigInt* x, uint8_t radix);
|
||||
|
Loading…
Reference in New Issue
Block a user