Remove BigFloat (#31)
Part of https://github.com/quickjs-ng/quickjs/issues/17
This commit is contained in:
parent
c1ed688610
commit
e449cb08ef
12 changed files with 72 additions and 1952 deletions
2
Makefile
2
Makefile
|
@ -54,7 +54,7 @@ prefix=/usr/local
|
||||||
#CONFIG_MSAN=y
|
#CONFIG_MSAN=y
|
||||||
# use UB sanitizer
|
# use UB sanitizer
|
||||||
#CONFIG_UBSAN=y
|
#CONFIG_UBSAN=y
|
||||||
# include the code for BigInt/BigFloat
|
# include the code for BigInt
|
||||||
CONFIG_BIGNUM=y
|
CONFIG_BIGNUM=y
|
||||||
|
|
||||||
OBJDIR=.obj
|
OBJDIR=.obj
|
||||||
|
|
|
@ -1,66 +0,0 @@
|
||||||
/*
|
|
||||||
* PI computation in Javascript using the QuickJS bigfloat type
|
|
||||||
* (binary floating point)
|
|
||||||
*/
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
/* compute PI with a precision of 'prec' bits */
|
|
||||||
function calc_pi() {
|
|
||||||
const CHUD_A = 13591409n;
|
|
||||||
const CHUD_B = 545140134n;
|
|
||||||
const CHUD_C = 640320n;
|
|
||||||
const CHUD_C3 = 10939058860032000n; /* C^3/24 */
|
|
||||||
const CHUD_BITS_PER_TERM = 47.11041313821584202247; /* log2(C/12)*3 */
|
|
||||||
|
|
||||||
/* return [P, Q, G] */
|
|
||||||
function chud_bs(a, b, need_G) {
|
|
||||||
var c, P, Q, G, P1, Q1, G1, P2, Q2, G2;
|
|
||||||
if (a == (b - 1n)) {
|
|
||||||
G = (2n * b - 1n) * (6n * b - 1n) * (6n * b - 5n);
|
|
||||||
P = BigFloat(G * (CHUD_B * b + CHUD_A));
|
|
||||||
if (b & 1n)
|
|
||||||
P = -P;
|
|
||||||
G = BigFloat(G);
|
|
||||||
Q = BigFloat(b * b * b * CHUD_C3);
|
|
||||||
} else {
|
|
||||||
c = (a + b) >> 1n;
|
|
||||||
[P1, Q1, G1] = chud_bs(a, c, true);
|
|
||||||
[P2, Q2, G2] = chud_bs(c, b, need_G);
|
|
||||||
P = P1 * Q2 + P2 * G1;
|
|
||||||
Q = Q1 * Q2;
|
|
||||||
if (need_G)
|
|
||||||
G = G1 * G2;
|
|
||||||
else
|
|
||||||
G = 0l;
|
|
||||||
}
|
|
||||||
return [P, Q, G];
|
|
||||||
}
|
|
||||||
|
|
||||||
var n, P, Q, G;
|
|
||||||
/* number of serie terms */
|
|
||||||
n = BigInt(Math.ceil(BigFloatEnv.prec / CHUD_BITS_PER_TERM)) + 10n;
|
|
||||||
[P, Q, G] = chud_bs(0n, n, false);
|
|
||||||
Q = Q / (P + Q * BigFloat(CHUD_A));
|
|
||||||
G = BigFloat((CHUD_C / 12n)) * BigFloat.sqrt(BigFloat(CHUD_C));
|
|
||||||
return Q * G;
|
|
||||||
}
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
var r, n_digits, n_bits;
|
|
||||||
if (typeof scriptArgs != "undefined") {
|
|
||||||
if (scriptArgs.length < 2) {
|
|
||||||
print("usage: pi n_digits");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
n_digits = scriptArgs[1];
|
|
||||||
} else {
|
|
||||||
n_digits = 1000;
|
|
||||||
}
|
|
||||||
n_bits = Math.ceil(n_digits * Math.log2(10));
|
|
||||||
/* we add more bits to reduce the probability of bad rounding for
|
|
||||||
the last digits */
|
|
||||||
BigFloatEnv.setPrec( () => {
|
|
||||||
r = calc_pi();
|
|
||||||
print(r.toFixed(n_digits, BigFloatEnv.RNDZ));
|
|
||||||
}, n_bits + 32);
|
|
||||||
})();
|
|
1
qjs.c
1
qjs.c
|
@ -109,7 +109,6 @@ static JSContext *JS_NewCustomContext(JSRuntime *rt)
|
||||||
return NULL;
|
return NULL;
|
||||||
#ifdef CONFIG_BIGNUM
|
#ifdef CONFIG_BIGNUM
|
||||||
if (bignum_ext) {
|
if (bignum_ext) {
|
||||||
JS_AddIntrinsicBigFloat(ctx);
|
|
||||||
JS_AddIntrinsicOperators(ctx);
|
JS_AddIntrinsicOperators(ctx);
|
||||||
JS_EnableBignumExt(ctx, TRUE);
|
JS_EnableBignumExt(ctx, TRUE);
|
||||||
}
|
}
|
||||||
|
|
2
qjsc.c
2
qjsc.c
|
@ -633,7 +633,6 @@ int main(int argc, char **argv)
|
||||||
ctx = JS_NewContext(rt);
|
ctx = JS_NewContext(rt);
|
||||||
#ifdef CONFIG_BIGNUM
|
#ifdef CONFIG_BIGNUM
|
||||||
if (bignum_ext) {
|
if (bignum_ext) {
|
||||||
JS_AddIntrinsicBigFloat(ctx);
|
|
||||||
JS_AddIntrinsicOperators(ctx);
|
JS_AddIntrinsicOperators(ctx);
|
||||||
JS_EnableBignumExt(ctx, TRUE);
|
JS_EnableBignumExt(ctx, TRUE);
|
||||||
}
|
}
|
||||||
|
@ -689,7 +688,6 @@ int main(int argc, char **argv)
|
||||||
#ifdef CONFIG_BIGNUM
|
#ifdef CONFIG_BIGNUM
|
||||||
if (bignum_ext) {
|
if (bignum_ext) {
|
||||||
fprintf(fo,
|
fprintf(fo,
|
||||||
" JS_AddIntrinsicBigFloat(ctx);\n"
|
|
||||||
" JS_AddIntrinsicOperators(ctx);\n"
|
" JS_AddIntrinsicOperators(ctx);\n"
|
||||||
" JS_EnableBignumExt(ctx, 1);\n");
|
" JS_EnableBignumExt(ctx, 1);\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -171,11 +171,6 @@ DEF(reason, "reason")
|
||||||
DEF(globalThis, "globalThis")
|
DEF(globalThis, "globalThis")
|
||||||
#ifdef CONFIG_BIGNUM
|
#ifdef CONFIG_BIGNUM
|
||||||
DEF(bigint, "bigint")
|
DEF(bigint, "bigint")
|
||||||
DEF(bigfloat, "bigfloat")
|
|
||||||
DEF(bigdecimal, "bigdecimal")
|
|
||||||
DEF(roundingMode, "roundingMode")
|
|
||||||
DEF(maximumSignificantDigits, "maximumSignificantDigits")
|
|
||||||
DEF(maximumFractionDigits, "maximumFractionDigits")
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_ATOMICS
|
#ifdef CONFIG_ATOMICS
|
||||||
DEF(not_equal, "not-equal")
|
DEF(not_equal, "not-equal")
|
||||||
|
@ -218,8 +213,6 @@ DEF(Float64Array, "Float64Array")
|
||||||
DEF(DataView, "DataView")
|
DEF(DataView, "DataView")
|
||||||
#ifdef CONFIG_BIGNUM
|
#ifdef CONFIG_BIGNUM
|
||||||
DEF(BigInt, "BigInt")
|
DEF(BigInt, "BigInt")
|
||||||
DEF(BigFloat, "BigFloat")
|
|
||||||
DEF(BigFloatEnv, "BigFloatEnv")
|
|
||||||
DEF(OperatorSet, "OperatorSet")
|
DEF(OperatorSet, "OperatorSet")
|
||||||
DEF(Operators, "Operators")
|
DEF(Operators, "Operators")
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -256,9 +256,6 @@ DEF( and, 1, 2, 1, none)
|
||||||
DEF( xor, 1, 2, 1, none)
|
DEF( xor, 1, 2, 1, none)
|
||||||
DEF( or, 1, 2, 1, none)
|
DEF( or, 1, 2, 1, none)
|
||||||
DEF(is_undefined_or_null, 1, 1, 1, none)
|
DEF(is_undefined_or_null, 1, 1, 1, none)
|
||||||
#ifdef CONFIG_BIGNUM
|
|
||||||
DEF( mul_pow10, 1, 2, 1, none)
|
|
||||||
#endif
|
|
||||||
/* must be the last non short and non temporary opcode */
|
/* must be the last non short and non temporary opcode */
|
||||||
DEF( nop, 1, 0, 0, none)
|
DEF( nop, 1, 0, 0, none)
|
||||||
|
|
||||||
|
|
12
quickjs.h
12
quickjs.h
|
@ -66,9 +66,8 @@ typedef uint32_t JSAtom;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
/* all tags with a reference count are negative */
|
/* all tags with a reference count are negative */
|
||||||
JS_TAG_FIRST = -10, /* first negative tag */
|
JS_TAG_FIRST = -9, /* first negative tag */
|
||||||
JS_TAG_BIG_INT = -10,
|
JS_TAG_BIG_INT = -9,
|
||||||
JS_TAG_BIG_FLOAT = -9,
|
|
||||||
JS_TAG_SYMBOL = -8,
|
JS_TAG_SYMBOL = -8,
|
||||||
JS_TAG_STRING = -7,
|
JS_TAG_STRING = -7,
|
||||||
JS_TAG_MODULE = -3, /* used internally */
|
JS_TAG_MODULE = -3, /* used internally */
|
||||||
|
@ -370,7 +369,6 @@ void JS_AddIntrinsicMapSet(JSContext *ctx);
|
||||||
void JS_AddIntrinsicTypedArrays(JSContext *ctx);
|
void JS_AddIntrinsicTypedArrays(JSContext *ctx);
|
||||||
void JS_AddIntrinsicPromise(JSContext *ctx);
|
void JS_AddIntrinsicPromise(JSContext *ctx);
|
||||||
void JS_AddIntrinsicBigInt(JSContext *ctx);
|
void JS_AddIntrinsicBigInt(JSContext *ctx);
|
||||||
void JS_AddIntrinsicBigFloat(JSContext *ctx);
|
|
||||||
/* enable operator overloading */
|
/* enable operator overloading */
|
||||||
void JS_AddIntrinsicOperators(JSContext *ctx);
|
void JS_AddIntrinsicOperators(JSContext *ctx);
|
||||||
/* enable "use math" */
|
/* enable "use math" */
|
||||||
|
@ -553,12 +551,6 @@ static inline JS_BOOL JS_IsBigInt(JSContext *ctx, JSValueConst v)
|
||||||
return tag == JS_TAG_BIG_INT;
|
return tag == JS_TAG_BIG_INT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline JS_BOOL JS_IsBigFloat(JSValueConst v)
|
|
||||||
{
|
|
||||||
int tag = JS_VALUE_GET_TAG(v);
|
|
||||||
return tag == JS_TAG_BIG_FLOAT;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline JS_BOOL JS_IsBool(JSValueConst v)
|
static inline JS_BOOL JS_IsBool(JSValueConst v)
|
||||||
{
|
{
|
||||||
return JS_VALUE_GET_TAG(v) == JS_TAG_BOOL;
|
return JS_VALUE_GET_TAG(v) == JS_TAG_BOOL;
|
||||||
|
|
208
repl.js
208
repl.js
|
@ -39,11 +39,6 @@ import * as os from "os";
|
||||||
var isFinite = g.isFinite;
|
var isFinite = g.isFinite;
|
||||||
var parseFloat = g.parseFloat;
|
var parseFloat = g.parseFloat;
|
||||||
|
|
||||||
/* XXX: use preprocessor ? */
|
|
||||||
var config_numcalc = (typeof os.open === "undefined");
|
|
||||||
var has_jscalc = (typeof Fraction === "function");
|
|
||||||
var has_bignum = (typeof BigFloat === "function");
|
|
||||||
|
|
||||||
var colors = {
|
var colors = {
|
||||||
none: "\x1b[0m",
|
none: "\x1b[0m",
|
||||||
black: "\x1b[30m",
|
black: "\x1b[30m",
|
||||||
|
@ -65,24 +60,7 @@ import * as os from "os";
|
||||||
bright_white: "\x1b[37;1m",
|
bright_white: "\x1b[37;1m",
|
||||||
};
|
};
|
||||||
|
|
||||||
var styles;
|
var styles = {
|
||||||
if (config_numcalc) {
|
|
||||||
styles = {
|
|
||||||
'default': 'black',
|
|
||||||
'comment': 'white',
|
|
||||||
'string': 'green',
|
|
||||||
'regex': 'cyan',
|
|
||||||
'number': 'green',
|
|
||||||
'keyword': 'blue',
|
|
||||||
'function': 'gray',
|
|
||||||
'type': 'bright_magenta',
|
|
||||||
'identifier': 'yellow',
|
|
||||||
'error': 'bright_red',
|
|
||||||
'result': 'black',
|
|
||||||
'error_msg': 'bright_red',
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
styles = {
|
|
||||||
'default': 'bright_green',
|
'default': 'bright_green',
|
||||||
'comment': 'white',
|
'comment': 'white',
|
||||||
'string': 'bright_cyan',
|
'string': 'bright_cyan',
|
||||||
|
@ -96,7 +74,6 @@ import * as os from "os";
|
||||||
'result': 'bright_white',
|
'result': 'bright_white',
|
||||||
'error_msg': 'bright_red',
|
'error_msg': 'bright_red',
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
var history = [];
|
var history = [];
|
||||||
var clip_board = "";
|
var clip_board = "";
|
||||||
|
@ -107,11 +84,7 @@ import * as os from "os";
|
||||||
var pstate = "";
|
var pstate = "";
|
||||||
var prompt = "";
|
var prompt = "";
|
||||||
var plen = 0;
|
var plen = 0;
|
||||||
var ps1;
|
var ps1 = "qjs > ";
|
||||||
if (config_numcalc)
|
|
||||||
ps1 = "> ";
|
|
||||||
else
|
|
||||||
ps1 = "qjs > ";
|
|
||||||
var ps2 = " ... ";
|
var ps2 = " ... ";
|
||||||
var utf8 = true;
|
var utf8 = true;
|
||||||
var show_time = false;
|
var show_time = false;
|
||||||
|
@ -931,48 +904,6 @@ import * as os from "os";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function bigfloat_to_string(a, radix) {
|
|
||||||
var s;
|
|
||||||
if (!BigFloat.isFinite(a)) {
|
|
||||||
/* NaN, Infinite */
|
|
||||||
if (eval_mode !== "math") {
|
|
||||||
return "BigFloat(" + a.toString() + ")";
|
|
||||||
} else {
|
|
||||||
return a.toString();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (a == 0) {
|
|
||||||
if (1 / a < 0)
|
|
||||||
s = "-0";
|
|
||||||
else
|
|
||||||
s = "0";
|
|
||||||
} else {
|
|
||||||
if (radix == 16) {
|
|
||||||
var s;
|
|
||||||
if (a < 0) {
|
|
||||||
a = -a;
|
|
||||||
s = "-";
|
|
||||||
} else {
|
|
||||||
s = "";
|
|
||||||
}
|
|
||||||
s += "0x" + a.toString(16);
|
|
||||||
} else {
|
|
||||||
s = a.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (typeof a === "bigfloat" && eval_mode !== "math") {
|
|
||||||
s += "l";
|
|
||||||
} else if (eval_mode !== "std" && s.indexOf(".") < 0 &&
|
|
||||||
((radix == 16 && s.indexOf("p") < 0) ||
|
|
||||||
(radix == 10 && s.indexOf("e") < 0))) {
|
|
||||||
/* add a decimal point so that the floating point type
|
|
||||||
is visible */
|
|
||||||
s += ".0";
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function bigint_to_string(a, radix) {
|
function bigint_to_string(a, radix) {
|
||||||
var s;
|
var s;
|
||||||
if (radix == 16) {
|
if (radix == 16) {
|
||||||
|
@ -1004,14 +935,6 @@ import * as os from "os";
|
||||||
std.puts(a);
|
std.puts(a);
|
||||||
} else if (stack.indexOf(a) >= 0) {
|
} else if (stack.indexOf(a) >= 0) {
|
||||||
std.puts("[circular]");
|
std.puts("[circular]");
|
||||||
} else if (has_jscalc && (a instanceof Fraction ||
|
|
||||||
a instanceof Complex ||
|
|
||||||
a instanceof Mod ||
|
|
||||||
a instanceof Polynomial ||
|
|
||||||
a instanceof PolyMod ||
|
|
||||||
a instanceof RationalFunction ||
|
|
||||||
a instanceof Series)) {
|
|
||||||
std.puts(a.toString());
|
|
||||||
} else {
|
} else {
|
||||||
stack.push(a);
|
stack.push(a);
|
||||||
if (Array.isArray(a)) {
|
if (Array.isArray(a)) {
|
||||||
|
@ -1057,10 +980,6 @@ import * as os from "os";
|
||||||
std.puts(number_to_string(a, hex_mode ? 16 : 10));
|
std.puts(number_to_string(a, hex_mode ? 16 : 10));
|
||||||
} else if (type === "bigint") {
|
} else if (type === "bigint") {
|
||||||
std.puts(bigint_to_string(a, hex_mode ? 16 : 10));
|
std.puts(bigint_to_string(a, hex_mode ? 16 : 10));
|
||||||
} else if (type === "bigfloat") {
|
|
||||||
std.puts(bigfloat_to_string(a, hex_mode ? 16 : 10));
|
|
||||||
} else if (type === "bigdecimal") {
|
|
||||||
std.puts(a.toString() + "m");
|
|
||||||
} else if (type === "symbol") {
|
} else if (type === "symbol") {
|
||||||
std.puts(String(a));
|
std.puts(String(a));
|
||||||
} else if (type === "function") {
|
} else if (type === "function") {
|
||||||
|
@ -1101,75 +1020,10 @@ import * as os from "os";
|
||||||
hex_mode = false;
|
hex_mode = false;
|
||||||
} else if (cmd === "t") {
|
} else if (cmd === "t") {
|
||||||
show_time = !show_time;
|
show_time = !show_time;
|
||||||
} else if (has_bignum && cmd === "p") {
|
|
||||||
param = expr.substring(cmd.length + 1).trim().split(" ");
|
|
||||||
if (param.length === 1 && param[0] === "") {
|
|
||||||
std.puts("BigFloat precision=" + prec + " bits (~" +
|
|
||||||
Math.floor(prec / log2_10) +
|
|
||||||
" digits), exponent size=" + expBits + " bits\n");
|
|
||||||
} else if (param[0] === "f16") {
|
|
||||||
prec = 11;
|
|
||||||
expBits = 5;
|
|
||||||
} else if (param[0] === "f32") {
|
|
||||||
prec = 24;
|
|
||||||
expBits = 8;
|
|
||||||
} else if (param[0] === "f64") {
|
|
||||||
prec = 53;
|
|
||||||
expBits = 11;
|
|
||||||
} else if (param[0] === "f128") {
|
|
||||||
prec = 113;
|
|
||||||
expBits = 15;
|
|
||||||
} else {
|
|
||||||
prec1 = parseInt(param[0]);
|
|
||||||
if (param.length >= 2)
|
|
||||||
expBits1 = parseInt(param[1]);
|
|
||||||
else
|
|
||||||
expBits1 = BigFloatEnv.expBitsMax;
|
|
||||||
if (Number.isNaN(prec1) ||
|
|
||||||
prec1 < BigFloatEnv.precMin ||
|
|
||||||
prec1 > BigFloatEnv.precMax) {
|
|
||||||
std.puts("Invalid precision\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (Number.isNaN(expBits1) ||
|
|
||||||
expBits1 < BigFloatEnv.expBitsMin ||
|
|
||||||
expBits1 > BigFloatEnv.expBitsMax) {
|
|
||||||
std.puts("Invalid exponent bits\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
prec = prec1;
|
|
||||||
expBits = expBits1;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
} else if (has_bignum && cmd === "digits") {
|
|
||||||
param = expr.substring(cmd.length + 1).trim();
|
|
||||||
prec1 = Math.ceil(parseFloat(param) * log2_10);
|
|
||||||
if (prec1 < BigFloatEnv.precMin ||
|
|
||||||
prec1 > BigFloatEnv.precMax) {
|
|
||||||
std.puts("Invalid precision\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
prec = prec1;
|
|
||||||
expBits = BigFloatEnv.expBitsMax;
|
|
||||||
return false;
|
|
||||||
} else if (has_bignum && cmd === "mode") {
|
|
||||||
param = expr.substring(cmd.length + 1).trim();
|
|
||||||
if (param === "") {
|
|
||||||
std.puts("Running mode=" + eval_mode + "\n");
|
|
||||||
} else if (param === "std" || param === "math") {
|
|
||||||
eval_mode = param;
|
|
||||||
} else {
|
|
||||||
std.puts("Invalid mode\n");
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
} else if (cmd === "clear") {
|
} else if (cmd === "clear") {
|
||||||
std.puts("\x1b[H\x1b[J");
|
std.puts("\x1b[H\x1b[J");
|
||||||
} else if (cmd === "q") {
|
} else if (cmd === "q") {
|
||||||
std.exit(0);
|
std.exit(0);
|
||||||
} else if (has_jscalc && cmd === "a") {
|
|
||||||
algebraicMode = true;
|
|
||||||
} else if (has_jscalc && cmd === "n") {
|
|
||||||
algebraicMode = false;
|
|
||||||
} else {
|
} else {
|
||||||
std.puts("Unknown directive: " + cmd + "\n");
|
std.puts("Unknown directive: " + cmd + "\n");
|
||||||
return false;
|
return false;
|
||||||
|
@ -1177,26 +1031,6 @@ import * as os from "os";
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config_numcalc) {
|
|
||||||
/* called by the GUI */
|
|
||||||
g.execCmd = function (cmd) {
|
|
||||||
switch(cmd) {
|
|
||||||
case "dec":
|
|
||||||
hex_mode = false;
|
|
||||||
break;
|
|
||||||
case "hex":
|
|
||||||
hex_mode = true;
|
|
||||||
break;
|
|
||||||
case "num":
|
|
||||||
algebraicMode = false;
|
|
||||||
break;
|
|
||||||
case "alg":
|
|
||||||
algebraicMode = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function help() {
|
function help() {
|
||||||
function sel(n) {
|
function sel(n) {
|
||||||
return n ? "*": " ";
|
return n ? "*": " ";
|
||||||
|
@ -1205,21 +1039,8 @@ import * as os from "os";
|
||||||
"\\x " + sel(hex_mode) + "hexadecimal number display\n" +
|
"\\x " + sel(hex_mode) + "hexadecimal number display\n" +
|
||||||
"\\d " + sel(!hex_mode) + "decimal number display\n" +
|
"\\d " + sel(!hex_mode) + "decimal number display\n" +
|
||||||
"\\t " + sel(show_time) + "toggle timing display\n" +
|
"\\t " + sel(show_time) + "toggle timing display\n" +
|
||||||
"\\clear clear the terminal\n");
|
"\\clear clear the terminal\n" +
|
||||||
if (has_jscalc) {
|
"\\q exit\n");
|
||||||
std.puts("\\a " + sel(algebraicMode) + "algebraic mode\n" +
|
|
||||||
"\\n " + sel(!algebraicMode) + "numeric mode\n");
|
|
||||||
}
|
|
||||||
if (has_bignum) {
|
|
||||||
std.puts("\\p [m [e]] set the BigFloat precision to 'm' bits\n" +
|
|
||||||
"\\digits n set the BigFloat precision to 'ceil(n*log2(10))' bits\n");
|
|
||||||
if (!has_jscalc) {
|
|
||||||
std.puts("\\mode [std|math] change the running mode (current = " + eval_mode + ")\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!config_numcalc) {
|
|
||||||
std.puts("\\q exit\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function eval_and_print(expr) {
|
function eval_and_print(expr) {
|
||||||
|
@ -1254,23 +1075,7 @@ import * as os from "os";
|
||||||
}
|
}
|
||||||
|
|
||||||
function cmd_start() {
|
function cmd_start() {
|
||||||
if (!config_numcalc) {
|
|
||||||
if (has_jscalc)
|
|
||||||
std.puts('QJSCalc - Type "\\h" for help\n');
|
|
||||||
else
|
|
||||||
std.puts('QuickJS - Type "\\h" for help\n');
|
std.puts('QuickJS - Type "\\h" for help\n');
|
||||||
}
|
|
||||||
if (has_bignum) {
|
|
||||||
log2_10 = Math.log(10) / Math.log(2);
|
|
||||||
prec = 113;
|
|
||||||
expBits = 15;
|
|
||||||
if (has_jscalc) {
|
|
||||||
eval_mode = "math";
|
|
||||||
/* XXX: numeric mode should always be the default ? */
|
|
||||||
g.algebraicMode = config_numcalc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd_readline_start();
|
cmd_readline_start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1314,12 +1119,7 @@ import * as os from "os";
|
||||||
}
|
}
|
||||||
mexpr = "";
|
mexpr = "";
|
||||||
|
|
||||||
if (has_bignum) {
|
|
||||||
BigFloatEnv.setPrec(eval_and_print.bind(null, expr),
|
|
||||||
prec, expBits);
|
|
||||||
} else {
|
|
||||||
eval_and_print(expr);
|
eval_and_print(expr);
|
||||||
}
|
|
||||||
level = 0;
|
level = 0;
|
||||||
|
|
||||||
/* run the garbage collector after each command */
|
/* run the garbage collector after each command */
|
||||||
|
|
|
@ -559,29 +559,6 @@ function float_arith(n)
|
||||||
return n * 1000;
|
return n * 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
function bigfloat_arith(n)
|
|
||||||
{
|
|
||||||
var i, j, sum, a, incr, a0;
|
|
||||||
global_res = 0;
|
|
||||||
a0 = BigFloat("0.1");
|
|
||||||
incr = BigFloat("1.1");
|
|
||||||
for(j = 0; j < n; j++) {
|
|
||||||
sum = 0;
|
|
||||||
a = a0;
|
|
||||||
for(i = 0; i < 1000; i++) {
|
|
||||||
sum += a * a;
|
|
||||||
a += incr;
|
|
||||||
}
|
|
||||||
global_res += sum;
|
|
||||||
}
|
|
||||||
return n * 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
function float256_arith(n)
|
|
||||||
{
|
|
||||||
return BigFloatEnv.setPrec(bigfloat_arith.bind(null, n), 237, 19);
|
|
||||||
}
|
|
||||||
|
|
||||||
function bigint_arith(n, bits)
|
function bigint_arith(n, bits)
|
||||||
{
|
{
|
||||||
var i, j, sum, a, incr, a0, sum0;
|
var i, j, sum, a, incr, a0, sum0;
|
||||||
|
@ -1001,10 +978,6 @@ function main(argc, argv, g)
|
||||||
test_list.push(bigint64_arith);
|
test_list.push(bigint64_arith);
|
||||||
test_list.push(bigint256_arith);
|
test_list.push(bigint256_arith);
|
||||||
}
|
}
|
||||||
if (typeof BigFloat == "function") {
|
|
||||||
/* BigFloat test */
|
|
||||||
test_list.push(float256_arith);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 1; i < argc;) {
|
for (i = 1; i < argc;) {
|
||||||
name = argv[i++];
|
name = argv[i++];
|
||||||
|
|
|
@ -147,95 +147,6 @@ function test_bigint_ext()
|
||||||
test_idiv1("ediv", 3n, 2n, [1n, -2n, -1n, 2n]);
|
test_idiv1("ediv", 3n, 2n, [1n, -2n, -1n, 2n]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function test_bigfloat()
|
|
||||||
{
|
|
||||||
var e, a, b, sqrt2;
|
|
||||||
|
|
||||||
assert(typeof 1n === "bigint");
|
|
||||||
assert(typeof 1l === "bigfloat");
|
|
||||||
assert(1 == 1.0l);
|
|
||||||
assert(1 !== 1.0l);
|
|
||||||
|
|
||||||
test_less(2l, 3l);
|
|
||||||
test_eq(3l, 3l);
|
|
||||||
|
|
||||||
test_less(2, 3l);
|
|
||||||
test_eq(3, 3l);
|
|
||||||
|
|
||||||
test_less(2.1, 3l);
|
|
||||||
test_eq(Math.sqrt(9), 3l);
|
|
||||||
|
|
||||||
test_less(2n, 3l);
|
|
||||||
test_eq(3n, 3l);
|
|
||||||
|
|
||||||
e = new BigFloatEnv(128);
|
|
||||||
assert(e.prec == 128);
|
|
||||||
a = BigFloat.sqrt(2l, e);
|
|
||||||
assert(a === BigFloat.parseFloat("0x1.6a09e667f3bcc908b2fb1366ea957d3e", 0, e));
|
|
||||||
assert(e.inexact === true);
|
|
||||||
assert(BigFloat.fpRound(a) == 0x1.6a09e667f3bcc908b2fb1366ea95l);
|
|
||||||
|
|
||||||
b = BigFloatEnv.setPrec(BigFloat.sqrt.bind(null, 2), 128);
|
|
||||||
assert(a === b);
|
|
||||||
|
|
||||||
assert(BigFloat.isNaN(BigFloat(NaN)));
|
|
||||||
assert(BigFloat.isFinite(1l));
|
|
||||||
assert(!BigFloat.isFinite(1l/0l));
|
|
||||||
|
|
||||||
assert(BigFloat.abs(-3l) === 3l);
|
|
||||||
assert(BigFloat.sign(-3l) === -1l);
|
|
||||||
|
|
||||||
assert(BigFloat.exp(0.2l) === 1.2214027581601698339210719946396742l);
|
|
||||||
assert(BigFloat.log(3l) === 1.0986122886681096913952452369225256l);
|
|
||||||
assert(BigFloat.pow(2.1l, 1.6l) === 3.277561666451861947162828744873745l);
|
|
||||||
|
|
||||||
assert(BigFloat.sin(-1l) === -0.841470984807896506652502321630299l);
|
|
||||||
assert(BigFloat.cos(1l) === 0.5403023058681397174009366074429766l);
|
|
||||||
assert(BigFloat.tan(0.1l) === 0.10033467208545054505808004578111154l);
|
|
||||||
|
|
||||||
assert(BigFloat.asin(0.3l) === 0.30469265401539750797200296122752915l);
|
|
||||||
assert(BigFloat.acos(0.4l) === 1.1592794807274085998465837940224159l);
|
|
||||||
assert(BigFloat.atan(0.7l) === 0.610725964389208616543758876490236l);
|
|
||||||
assert(BigFloat.atan2(7.1l, -5.1l) === 2.1937053809751415549388104628759813l);
|
|
||||||
|
|
||||||
assert(BigFloat.floor(2.5l) === 2l);
|
|
||||||
assert(BigFloat.ceil(2.5l) === 3l);
|
|
||||||
assert(BigFloat.trunc(-2.5l) === -2l);
|
|
||||||
assert(BigFloat.round(2.5l) === 3l);
|
|
||||||
|
|
||||||
assert(BigFloat.fmod(3l,2l) === 1l);
|
|
||||||
assert(BigFloat.remainder(3l,2l) === -1l);
|
|
||||||
|
|
||||||
/* string conversion */
|
|
||||||
assert((1234.125l).toString(), "1234.125");
|
|
||||||
assert((1234.125l).toFixed(2), "1234.13");
|
|
||||||
assert((1234.125l).toFixed(2, "down"), "1234.12");
|
|
||||||
assert((1234.125l).toExponential(), "1.234125e+3");
|
|
||||||
assert((1234.125l).toExponential(5), "1.23413e+3");
|
|
||||||
assert((1234.125l).toExponential(5, BigFloatEnv.RNDZ), "1.23412e+3");
|
|
||||||
assert((1234.125l).toPrecision(6), "1234.13");
|
|
||||||
assert((1234.125l).toPrecision(6, BigFloatEnv.RNDZ), "1234.12");
|
|
||||||
|
|
||||||
/* string conversion with binary base */
|
|
||||||
assert((0x123.438l).toString(16), "123.438");
|
|
||||||
assert((0x323.438l).toString(16), "323.438");
|
|
||||||
assert((0x723.438l).toString(16), "723.438");
|
|
||||||
assert((0xf23.438l).toString(16), "f23.438");
|
|
||||||
assert((0x123.438l).toFixed(2, BigFloatEnv.RNDNA, 16), "123.44");
|
|
||||||
assert((0x323.438l).toFixed(2, BigFloatEnv.RNDNA, 16), "323.44");
|
|
||||||
assert((0x723.438l).toFixed(2, BigFloatEnv.RNDNA, 16), "723.44");
|
|
||||||
assert((0xf23.438l).toFixed(2, BigFloatEnv.RNDNA, 16), "f23.44");
|
|
||||||
assert((0x0.0000438l).toFixed(6, BigFloatEnv.RNDNA, 16), "0.000044");
|
|
||||||
assert((0x1230000000l).toFixed(1, BigFloatEnv.RNDNA, 16), "1230000000.0");
|
|
||||||
assert((0x123.438l).toPrecision(5, BigFloatEnv.RNDNA, 16), "123.44");
|
|
||||||
assert((0x123.438l).toPrecision(5, BigFloatEnv.RNDZ, 16), "123.43");
|
|
||||||
assert((0x323.438l).toPrecision(5, BigFloatEnv.RNDNA, 16), "323.44");
|
|
||||||
assert((0x723.438l).toPrecision(5, BigFloatEnv.RNDNA, 16), "723.44");
|
|
||||||
assert((-0xf23.438l).toPrecision(5, BigFloatEnv.RNDD, 16), "-f23.44");
|
|
||||||
assert((0x123.438l).toExponential(4, BigFloatEnv.RNDNA, 16), "1.2344p+8");
|
|
||||||
}
|
|
||||||
|
|
||||||
test_bigint1();
|
test_bigint1();
|
||||||
test_bigint2();
|
test_bigint2();
|
||||||
test_bigint_ext();
|
test_bigint_ext();
|
||||||
test_bigfloat();
|
|
||||||
|
|
|
@ -87,7 +87,6 @@ function toStr(a)
|
||||||
case "string":
|
case "string":
|
||||||
return a.__quote();
|
return a.__quote();
|
||||||
case "number":
|
case "number":
|
||||||
case "bigfloat":
|
|
||||||
if (a == 0 && 1 / a < 0)
|
if (a == 0 && 1 / a < 0)
|
||||||
return "-0";
|
return "-0";
|
||||||
else
|
else
|
||||||
|
@ -155,14 +154,6 @@ function bjson_test_all()
|
||||||
bjson_test([BigInt("1"), -BigInt("0x123456789"),
|
bjson_test([BigInt("1"), -BigInt("0x123456789"),
|
||||||
BigInt("0x123456789abcdef123456789abcdef")]);
|
BigInt("0x123456789abcdef123456789abcdef")]);
|
||||||
}
|
}
|
||||||
if (typeof BigFloat !== "undefined") {
|
|
||||||
BigFloatEnv.setPrec(function () {
|
|
||||||
bjson_test([BigFloat("0.1"), BigFloat("-1e30"), BigFloat("0"),
|
|
||||||
BigFloat("-0"), BigFloat("Infinity"), BigFloat("-Infinity"),
|
|
||||||
0.0 / BigFloat("0"), BigFloat.MAX_VALUE,
|
|
||||||
BigFloat.MIN_VALUE]);
|
|
||||||
}, 113, 15);
|
|
||||||
}
|
|
||||||
|
|
||||||
bjson_test([new Date(1234), new String("abc"), new Number(-12.1), new Boolean(true)]);
|
bjson_test([new Date(1234), new String("abc"), new Number(-12.1), new Boolean(true)]);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue