mirror of
				https://github.com/bellard/quickjs.git
				synced 2025-05-29 01:49:18 +08:00 
			
		
		
		
	removed bignum support and qjscalc - added optimized BigInt implementation
This commit is contained in:
		
							parent
							
								
									837a697588
								
							
						
					
					
						commit
						61e8b94428
					
				
							
								
								
									
										43
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										43
									
								
								Makefile
									
									
									
									
									
								
							@ -51,9 +51,6 @@ PREFIX?=/usr/local
 | 
				
			|||||||
# use UB sanitizer
 | 
					# use UB sanitizer
 | 
				
			||||||
#CONFIG_UBSAN=y
 | 
					#CONFIG_UBSAN=y
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# include the code for BigFloat/BigDecimal and math mode
 | 
					 | 
				
			||||||
CONFIG_BIGNUM=y
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
OBJDIR=.obj
 | 
					OBJDIR=.obj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ifdef CONFIG_ASAN
 | 
					ifdef CONFIG_ASAN
 | 
				
			||||||
@ -137,9 +134,6 @@ ifdef CONFIG_WERROR
 | 
				
			|||||||
CFLAGS+=-Werror
 | 
					CFLAGS+=-Werror
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
DEFINES:=-D_GNU_SOURCE -DCONFIG_VERSION=\"$(shell cat VERSION)\"
 | 
					DEFINES:=-D_GNU_SOURCE -DCONFIG_VERSION=\"$(shell cat VERSION)\"
 | 
				
			||||||
ifdef CONFIG_BIGNUM
 | 
					 | 
				
			||||||
DEFINES+=-DCONFIG_BIGNUM
 | 
					 | 
				
			||||||
endif
 | 
					 | 
				
			||||||
ifdef CONFIG_WIN32
 | 
					ifdef CONFIG_WIN32
 | 
				
			||||||
DEFINES+=-D__USE_MINGW_ANSI_STDIO # for standard snprintf behavior
 | 
					DEFINES+=-D__USE_MINGW_ANSI_STDIO # for standard snprintf behavior
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
@ -201,9 +195,6 @@ else
 | 
				
			|||||||
QJSC_CC=$(CC)
 | 
					QJSC_CC=$(CC)
 | 
				
			||||||
QJSC=./qjsc$(EXE)
 | 
					QJSC=./qjsc$(EXE)
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
ifndef CONFIG_WIN32
 | 
					 | 
				
			||||||
PROGS+=qjscalc
 | 
					 | 
				
			||||||
endif
 | 
					 | 
				
			||||||
ifdef CONFIG_M32
 | 
					ifdef CONFIG_M32
 | 
				
			||||||
PROGS+=qjs32 qjs32_s
 | 
					PROGS+=qjs32 qjs32_s
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
@ -228,12 +219,9 @@ endif
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
all: $(OBJDIR) $(OBJDIR)/quickjs.check.o $(OBJDIR)/qjs.check.o $(PROGS)
 | 
					all: $(OBJDIR) $(OBJDIR)/quickjs.check.o $(OBJDIR)/qjs.check.o $(PROGS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
QJS_LIB_OBJS=$(OBJDIR)/quickjs.o $(OBJDIR)/libregexp.o $(OBJDIR)/libunicode.o $(OBJDIR)/cutils.o $(OBJDIR)/quickjs-libc.o $(OBJDIR)/libbf.o
 | 
					QJS_LIB_OBJS=$(OBJDIR)/quickjs.o $(OBJDIR)/libregexp.o $(OBJDIR)/libunicode.o $(OBJDIR)/cutils.o $(OBJDIR)/quickjs-libc.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
QJS_OBJS=$(OBJDIR)/qjs.o $(OBJDIR)/repl.o $(QJS_LIB_OBJS)
 | 
					QJS_OBJS=$(OBJDIR)/qjs.o $(OBJDIR)/repl.o $(QJS_LIB_OBJS)
 | 
				
			||||||
ifdef CONFIG_BIGNUM
 | 
					 | 
				
			||||||
QJS_OBJS+=$(OBJDIR)/qjscalc.o
 | 
					 | 
				
			||||||
endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
HOST_LIBS=-lm -ldl -lpthread
 | 
					HOST_LIBS=-lm -ldl -lpthread
 | 
				
			||||||
LIBS=-lm
 | 
					LIBS=-lm
 | 
				
			||||||
@ -289,9 +277,6 @@ qjs32_s: $(patsubst %.o, %.m32s.o, $(QJS_OBJS))
 | 
				
			|||||||
	$(CC) -m32 $(LDFLAGS) -o $@ $^ $(LIBS)
 | 
						$(CC) -m32 $(LDFLAGS) -o $@ $^ $(LIBS)
 | 
				
			||||||
	@size $@
 | 
						@size $@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
qjscalc: qjs
 | 
					 | 
				
			||||||
	ln -sf $< $@
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ifdef CONFIG_LTO
 | 
					ifdef CONFIG_LTO
 | 
				
			||||||
LTOEXT=.lto
 | 
					LTOEXT=.lto
 | 
				
			||||||
else
 | 
					else
 | 
				
			||||||
@ -312,9 +297,6 @@ libquickjs.fuzz.a: $(patsubst %.o, %.fuzz.o, $(QJS_LIB_OBJS))
 | 
				
			|||||||
repl.c: $(QJSC) repl.js
 | 
					repl.c: $(QJSC) repl.js
 | 
				
			||||||
	$(QJSC) -c -o $@ -m repl.js
 | 
						$(QJSC) -c -o $@ -m repl.js
 | 
				
			||||||
 | 
					
 | 
				
			||||||
qjscalc.c: $(QJSC) qjscalc.js
 | 
					 | 
				
			||||||
	$(QJSC) -fbignum -c -o $@ qjscalc.js
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ifneq ($(wildcard unicode/UnicodeData.txt),)
 | 
					ifneq ($(wildcard unicode/UnicodeData.txt),)
 | 
				
			||||||
$(OBJDIR)/libunicode.o $(OBJDIR)/libunicode.m32.o $(OBJDIR)/libunicode.m32s.o \
 | 
					$(OBJDIR)/libunicode.o $(OBJDIR)/libunicode.m32.o $(OBJDIR)/libunicode.m32s.o \
 | 
				
			||||||
    $(OBJDIR)/libunicode.nolto.o: libunicode-table.h
 | 
					    $(OBJDIR)/libunicode.nolto.o: libunicode-table.h
 | 
				
			||||||
@ -371,7 +353,7 @@ unicode_gen: $(OBJDIR)/unicode_gen.host.o $(OBJDIR)/cutils.host.o libunicode.c u
 | 
				
			|||||||
	$(HOST_CC) $(LDFLAGS) $(CFLAGS) -o $@ $(OBJDIR)/unicode_gen.host.o $(OBJDIR)/cutils.host.o
 | 
						$(HOST_CC) $(LDFLAGS) $(CFLAGS) -o $@ $(OBJDIR)/unicode_gen.host.o $(OBJDIR)/cutils.host.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
clean:
 | 
					clean:
 | 
				
			||||||
	rm -f repl.c qjscalc.c out.c
 | 
						rm -f repl.c out.c
 | 
				
			||||||
	rm -f *.a *.o *.d *~ unicode_gen regexp_test fuzz_eval fuzz_compile fuzz_regexp $(PROGS)
 | 
						rm -f *.a *.o *.d *~ unicode_gen regexp_test fuzz_eval fuzz_compile fuzz_regexp $(PROGS)
 | 
				
			||||||
	rm -f hello.c test_fib.c
 | 
						rm -f hello.c test_fib.c
 | 
				
			||||||
	rm -f examples/*.so tests/*.so
 | 
						rm -f examples/*.so tests/*.so
 | 
				
			||||||
@ -383,7 +365,6 @@ install: all
 | 
				
			|||||||
	mkdir -p "$(DESTDIR)$(PREFIX)/bin"
 | 
						mkdir -p "$(DESTDIR)$(PREFIX)/bin"
 | 
				
			||||||
	$(STRIP) qjs$(EXE) qjsc$(EXE)
 | 
						$(STRIP) qjs$(EXE) qjsc$(EXE)
 | 
				
			||||||
	install -m755 qjs$(EXE) qjsc$(EXE) "$(DESTDIR)$(PREFIX)/bin"
 | 
						install -m755 qjs$(EXE) qjsc$(EXE) "$(DESTDIR)$(PREFIX)/bin"
 | 
				
			||||||
	ln -sf qjs$(EXE) "$(DESTDIR)$(PREFIX)/bin/qjscalc$(EXE)"
 | 
					 | 
				
			||||||
	mkdir -p "$(DESTDIR)$(PREFIX)/lib/quickjs"
 | 
						mkdir -p "$(DESTDIR)$(PREFIX)/lib/quickjs"
 | 
				
			||||||
	install -m644 libquickjs.a "$(DESTDIR)$(PREFIX)/lib/quickjs"
 | 
						install -m644 libquickjs.a "$(DESTDIR)$(PREFIX)/lib/quickjs"
 | 
				
			||||||
ifdef CONFIG_LTO
 | 
					ifdef CONFIG_LTO
 | 
				
			||||||
@ -468,35 +449,21 @@ test: qjs
 | 
				
			|||||||
	./qjs tests/test_language.js
 | 
						./qjs tests/test_language.js
 | 
				
			||||||
	./qjs --std tests/test_builtin.js
 | 
						./qjs --std tests/test_builtin.js
 | 
				
			||||||
	./qjs tests/test_loop.js
 | 
						./qjs tests/test_loop.js
 | 
				
			||||||
	./qjs tests/test_bignum.js
 | 
						./qjs tests/test_bigint.js
 | 
				
			||||||
	./qjs tests/test_std.js
 | 
						./qjs tests/test_std.js
 | 
				
			||||||
	./qjs tests/test_worker.js
 | 
						./qjs tests/test_worker.js
 | 
				
			||||||
ifdef CONFIG_SHARED_LIBS
 | 
					ifdef CONFIG_SHARED_LIBS
 | 
				
			||||||
ifdef CONFIG_BIGNUM
 | 
					 | 
				
			||||||
	./qjs --bignum tests/test_bjson.js
 | 
					 | 
				
			||||||
else
 | 
					 | 
				
			||||||
	./qjs tests/test_bjson.js
 | 
						./qjs tests/test_bjson.js
 | 
				
			||||||
endif
 | 
					 | 
				
			||||||
	./qjs examples/test_point.js
 | 
						./qjs examples/test_point.js
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
ifdef CONFIG_BIGNUM
 | 
					 | 
				
			||||||
	./qjs --bignum tests/test_op_overloading.js
 | 
					 | 
				
			||||||
	./qjs --bignum tests/test_bigfloat.js
 | 
					 | 
				
			||||||
	./qjs --qjscalc tests/test_qjscalc.js
 | 
					 | 
				
			||||||
endif
 | 
					 | 
				
			||||||
ifdef CONFIG_M32
 | 
					ifdef CONFIG_M32
 | 
				
			||||||
	./qjs32 tests/test_closure.js
 | 
						./qjs32 tests/test_closure.js
 | 
				
			||||||
	./qjs32 tests/test_language.js
 | 
						./qjs32 tests/test_language.js
 | 
				
			||||||
	./qjs32 --std tests/test_builtin.js
 | 
						./qjs32 --std tests/test_builtin.js
 | 
				
			||||||
	./qjs32 tests/test_loop.js
 | 
						./qjs32 tests/test_loop.js
 | 
				
			||||||
	./qjs32 tests/test_bignum.js
 | 
						./qjs32 tests/test_bigint.js
 | 
				
			||||||
	./qjs32 tests/test_std.js
 | 
						./qjs32 tests/test_std.js
 | 
				
			||||||
	./qjs32 tests/test_worker.js
 | 
						./qjs32 tests/test_worker.js
 | 
				
			||||||
ifdef CONFIG_BIGNUM
 | 
					 | 
				
			||||||
	./qjs32 --bignum tests/test_op_overloading.js
 | 
					 | 
				
			||||||
	./qjs32 --bignum tests/test_bigfloat.js
 | 
					 | 
				
			||||||
	./qjs32 --qjscalc tests/test_qjscalc.js
 | 
					 | 
				
			||||||
endif
 | 
					 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
stats: qjs qjs32
 | 
					stats: qjs qjs32
 | 
				
			||||||
@ -556,7 +523,7 @@ node-test:
 | 
				
			|||||||
	node tests/test_language.js
 | 
						node tests/test_language.js
 | 
				
			||||||
	node tests/test_builtin.js
 | 
						node tests/test_builtin.js
 | 
				
			||||||
	node tests/test_loop.js
 | 
						node tests/test_loop.js
 | 
				
			||||||
	node tests/test_bignum.js
 | 
						node tests/test_bigint.js
 | 
				
			||||||
 | 
					
 | 
				
			||||||
node-microbench:
 | 
					node-microbench:
 | 
				
			||||||
	node tests/microbench.js -s microbench-node.txt
 | 
						node tests/microbench.js -s microbench-node.txt
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										1
									
								
								TODO
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								TODO
									
									
									
									
									
								
							@ -38,7 +38,6 @@ REPL:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
Optimization ideas:
 | 
					Optimization ideas:
 | 
				
			||||||
- 64-bit atoms in 64-bit mode ?
 | 
					- 64-bit atoms in 64-bit mode ?
 | 
				
			||||||
- 64-bit small bigint in 64-bit mode ?
 | 
					 | 
				
			||||||
- reuse stack slots for disjoint scopes, if strip
 | 
					- reuse stack slots for disjoint scopes, if strip
 | 
				
			||||||
- add heuristic to avoid some cycles in closures
 | 
					- add heuristic to avoid some cycles in closures
 | 
				
			||||||
- small String (0-2 charcodes) with immediate storage
 | 
					- small String (0-2 charcodes) with immediate storage
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										20
									
								
								cutils.h
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								cutils.h
									
									
									
									
									
								
							@ -344,4 +344,24 @@ void rqsort(void *base, size_t nmemb, size_t size,
 | 
				
			|||||||
            int (*cmp)(const void *, const void *, void *),
 | 
					            int (*cmp)(const void *, const void *, void *),
 | 
				
			||||||
            void *arg);
 | 
					            void *arg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline uint64_t float64_as_uint64(double d)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    union {
 | 
				
			||||||
 | 
					        double d;
 | 
				
			||||||
 | 
					        uint64_t u64;
 | 
				
			||||||
 | 
					    } u;
 | 
				
			||||||
 | 
					    u.d = d;
 | 
				
			||||||
 | 
					    return u.u64;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline double uint64_as_float64(uint64_t u64)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    union {
 | 
				
			||||||
 | 
					        double d;
 | 
				
			||||||
 | 
					        uint64_t u64;
 | 
				
			||||||
 | 
					    } u;
 | 
				
			||||||
 | 
					    u.u64 = u64;
 | 
				
			||||||
 | 
					    return u.d;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif  /* CUTILS_H */
 | 
					#endif  /* CUTILS_H */
 | 
				
			||||||
 | 
				
			|||||||
@ -1,68 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
 * PI computation in Javascript using the QuickJS bigdecimal type
 | 
					 | 
				
			||||||
 * (decimal floating point)
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
"use strict";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* compute PI with a precision of 'prec' digits */
 | 
					 | 
				
			||||||
function calc_pi(prec) {
 | 
					 | 
				
			||||||
    const CHUD_A = 13591409m;
 | 
					 | 
				
			||||||
    const CHUD_B = 545140134m;
 | 
					 | 
				
			||||||
    const CHUD_C = 640320m;
 | 
					 | 
				
			||||||
    const CHUD_C3 = 10939058860032000m; /* C^3/24 */
 | 
					 | 
				
			||||||
    const CHUD_DIGITS_PER_TERM = 14.18164746272548; /* log10(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, b1;
 | 
					 | 
				
			||||||
        if (a == (b - 1n)) {
 | 
					 | 
				
			||||||
            b1 = BigDecimal(b);
 | 
					 | 
				
			||||||
            G = (2m * b1 - 1m) * (6m * b1 - 1m) * (6m * b1 - 5m);
 | 
					 | 
				
			||||||
            P = G * (CHUD_B * b1 + CHUD_A);
 | 
					 | 
				
			||||||
            if (b & 1n)
 | 
					 | 
				
			||||||
                P = -P;
 | 
					 | 
				
			||||||
            G = G;
 | 
					 | 
				
			||||||
            Q = b1 * b1 * b1 * 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 = 0m;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return [P, Q, G];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    var n, P, Q, G;
 | 
					 | 
				
			||||||
    /* number of serie terms */
 | 
					 | 
				
			||||||
    n = BigInt(Math.ceil(prec / CHUD_DIGITS_PER_TERM)) + 10n;
 | 
					 | 
				
			||||||
    [P, Q, G] = chud_bs(0n, n, false);
 | 
					 | 
				
			||||||
    Q = BigDecimal.div(Q, (P + Q * CHUD_A),
 | 
					 | 
				
			||||||
                       { roundingMode: "half-even",
 | 
					 | 
				
			||||||
                         maximumSignificantDigits: prec });
 | 
					 | 
				
			||||||
    G = (CHUD_C / 12m) * BigDecimal.sqrt(CHUD_C,
 | 
					 | 
				
			||||||
                                         { roundingMode: "half-even",
 | 
					 | 
				
			||||||
                                           maximumSignificantDigits: prec });
 | 
					 | 
				
			||||||
    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] | 0;
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        n_digits = 1000;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    /* we add more digits to reduce the probability of bad rounding for
 | 
					 | 
				
			||||||
       the last digits */
 | 
					 | 
				
			||||||
    r = calc_pi(n_digits + 20);
 | 
					 | 
				
			||||||
    print(r.toFixed(n_digits, "down"));
 | 
					 | 
				
			||||||
})();
 | 
					 | 
				
			||||||
@ -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);
 | 
					 | 
				
			||||||
})();
 | 
					 | 
				
			||||||
							
								
								
									
										535
									
								
								libbf.h
									
									
									
									
									
								
							
							
						
						
									
										535
									
								
								libbf.h
									
									
									
									
									
								
							@ -1,535 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
 * Tiny arbitrary precision floating point library
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Copyright (c) 2017-2021 Fabrice Bellard
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
					 | 
				
			||||||
 * of this software and associated documentation files (the "Software"), to deal
 | 
					 | 
				
			||||||
 * in the Software without restriction, including without limitation the rights
 | 
					 | 
				
			||||||
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
					 | 
				
			||||||
 * copies of the Software, and to permit persons to whom the Software is
 | 
					 | 
				
			||||||
 * furnished to do so, subject to the following conditions:
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * The above copyright notice and this permission notice shall be included in
 | 
					 | 
				
			||||||
 * all copies or substantial portions of the Software.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
					 | 
				
			||||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
					 | 
				
			||||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
					 | 
				
			||||||
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
					 | 
				
			||||||
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
					 | 
				
			||||||
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
					 | 
				
			||||||
 * THE SOFTWARE.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#ifndef LIBBF_H
 | 
					 | 
				
			||||||
#define LIBBF_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <stddef.h>
 | 
					 | 
				
			||||||
#include <stdint.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if defined(__SIZEOF_INT128__) && (INTPTR_MAX >= INT64_MAX)
 | 
					 | 
				
			||||||
#define LIMB_LOG2_BITS 6
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
#define LIMB_LOG2_BITS 5
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define LIMB_BITS (1 << LIMB_LOG2_BITS)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if LIMB_BITS == 64
 | 
					 | 
				
			||||||
typedef __int128 int128_t;
 | 
					 | 
				
			||||||
typedef unsigned __int128 uint128_t;
 | 
					 | 
				
			||||||
typedef int64_t slimb_t;
 | 
					 | 
				
			||||||
typedef uint64_t limb_t;
 | 
					 | 
				
			||||||
typedef uint128_t dlimb_t;
 | 
					 | 
				
			||||||
#define BF_RAW_EXP_MIN INT64_MIN
 | 
					 | 
				
			||||||
#define BF_RAW_EXP_MAX INT64_MAX
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define LIMB_DIGITS 19
 | 
					 | 
				
			||||||
#define BF_DEC_BASE UINT64_C(10000000000000000000)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef int32_t slimb_t;
 | 
					 | 
				
			||||||
typedef uint32_t limb_t;
 | 
					 | 
				
			||||||
typedef uint64_t dlimb_t;
 | 
					 | 
				
			||||||
#define BF_RAW_EXP_MIN INT32_MIN
 | 
					 | 
				
			||||||
#define BF_RAW_EXP_MAX INT32_MAX
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define LIMB_DIGITS 9
 | 
					 | 
				
			||||||
#define BF_DEC_BASE 1000000000U
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* in bits */
 | 
					 | 
				
			||||||
/* minimum number of bits for the exponent */
 | 
					 | 
				
			||||||
#define BF_EXP_BITS_MIN 3
 | 
					 | 
				
			||||||
/* maximum number of bits for the exponent */
 | 
					 | 
				
			||||||
#define BF_EXP_BITS_MAX (LIMB_BITS - 3)
 | 
					 | 
				
			||||||
/* extended range for exponent, used internally */
 | 
					 | 
				
			||||||
#define BF_EXT_EXP_BITS_MAX (BF_EXP_BITS_MAX + 1)
 | 
					 | 
				
			||||||
/* minimum possible precision */
 | 
					 | 
				
			||||||
#define BF_PREC_MIN 2
 | 
					 | 
				
			||||||
/* minimum possible precision */
 | 
					 | 
				
			||||||
#define BF_PREC_MAX (((limb_t)1 << (LIMB_BITS - 2)) - 2)
 | 
					 | 
				
			||||||
/* some operations support infinite precision */
 | 
					 | 
				
			||||||
#define BF_PREC_INF (BF_PREC_MAX + 1) /* infinite precision */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if LIMB_BITS == 64
 | 
					 | 
				
			||||||
#define BF_CHKSUM_MOD (UINT64_C(975620677) * UINT64_C(9795002197))
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
#define BF_CHKSUM_MOD 975620677U
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define BF_EXP_ZERO BF_RAW_EXP_MIN
 | 
					 | 
				
			||||||
#define BF_EXP_INF (BF_RAW_EXP_MAX - 1)
 | 
					 | 
				
			||||||
#define BF_EXP_NAN BF_RAW_EXP_MAX
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* +/-zero is represented with expn = BF_EXP_ZERO and len = 0,
 | 
					 | 
				
			||||||
   +/-infinity is represented with expn = BF_EXP_INF and len = 0,
 | 
					 | 
				
			||||||
   NaN is represented with expn = BF_EXP_NAN and len = 0 (sign is ignored)
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
typedef struct {
 | 
					 | 
				
			||||||
    struct bf_context_t *ctx;
 | 
					 | 
				
			||||||
    int sign;
 | 
					 | 
				
			||||||
    slimb_t expn;
 | 
					 | 
				
			||||||
    limb_t len;
 | 
					 | 
				
			||||||
    limb_t *tab;
 | 
					 | 
				
			||||||
} bf_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct {
 | 
					 | 
				
			||||||
    /* must be kept identical to bf_t */
 | 
					 | 
				
			||||||
    struct bf_context_t *ctx;
 | 
					 | 
				
			||||||
    int sign;
 | 
					 | 
				
			||||||
    slimb_t expn;
 | 
					 | 
				
			||||||
    limb_t len;
 | 
					 | 
				
			||||||
    limb_t *tab;
 | 
					 | 
				
			||||||
} bfdec_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef enum {
 | 
					 | 
				
			||||||
    BF_RNDN, /* round to nearest, ties to even */
 | 
					 | 
				
			||||||
    BF_RNDZ, /* round to zero */
 | 
					 | 
				
			||||||
    BF_RNDD, /* round to -inf (the code relies on (BF_RNDD xor BF_RNDU) = 1) */
 | 
					 | 
				
			||||||
    BF_RNDU, /* round to +inf */
 | 
					 | 
				
			||||||
    BF_RNDNA, /* round to nearest, ties away from zero */
 | 
					 | 
				
			||||||
    BF_RNDA, /* round away from zero */
 | 
					 | 
				
			||||||
    BF_RNDF, /* faithful rounding (nondeterministic, either RNDD or RNDU,
 | 
					 | 
				
			||||||
                inexact flag is always set)  */
 | 
					 | 
				
			||||||
} bf_rnd_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* allow subnormal numbers. Only available if the number of exponent
 | 
					 | 
				
			||||||
   bits is <= BF_EXP_BITS_USER_MAX and prec != BF_PREC_INF. */
 | 
					 | 
				
			||||||
#define BF_FLAG_SUBNORMAL (1 << 3)
 | 
					 | 
				
			||||||
/* 'prec' is the precision after the radix point instead of the whole
 | 
					 | 
				
			||||||
   mantissa. Can only be used with bf_round() and
 | 
					 | 
				
			||||||
   bfdec_[add|sub|mul|div|sqrt|round](). */
 | 
					 | 
				
			||||||
#define BF_FLAG_RADPNT_PREC (1 << 4)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define BF_RND_MASK 0x7
 | 
					 | 
				
			||||||
#define BF_EXP_BITS_SHIFT 5
 | 
					 | 
				
			||||||
#define BF_EXP_BITS_MASK 0x3f
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* shortcut for bf_set_exp_bits(BF_EXT_EXP_BITS_MAX) */
 | 
					 | 
				
			||||||
#define BF_FLAG_EXT_EXP (BF_EXP_BITS_MASK << BF_EXP_BITS_SHIFT)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* contains the rounding mode and number of exponents bits */
 | 
					 | 
				
			||||||
typedef uint32_t bf_flags_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef void *bf_realloc_func_t(void *opaque, void *ptr, size_t size);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct {
 | 
					 | 
				
			||||||
    bf_t val;
 | 
					 | 
				
			||||||
    limb_t prec;
 | 
					 | 
				
			||||||
} BFConstCache;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct bf_context_t {
 | 
					 | 
				
			||||||
    void *realloc_opaque;
 | 
					 | 
				
			||||||
    bf_realloc_func_t *realloc_func;
 | 
					 | 
				
			||||||
    BFConstCache log2_cache;
 | 
					 | 
				
			||||||
    BFConstCache pi_cache;
 | 
					 | 
				
			||||||
    struct BFNTTState *ntt_state;
 | 
					 | 
				
			||||||
} bf_context_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline int bf_get_exp_bits(bf_flags_t flags)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int e;
 | 
					 | 
				
			||||||
    e = (flags >> BF_EXP_BITS_SHIFT) & BF_EXP_BITS_MASK;
 | 
					 | 
				
			||||||
    if (e == BF_EXP_BITS_MASK)
 | 
					 | 
				
			||||||
        return BF_EXP_BITS_MAX + 1;
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
        return BF_EXP_BITS_MAX - e;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline bf_flags_t bf_set_exp_bits(int n)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return ((BF_EXP_BITS_MAX - n) & BF_EXP_BITS_MASK) << BF_EXP_BITS_SHIFT;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* returned status */
 | 
					 | 
				
			||||||
#define BF_ST_INVALID_OP  (1 << 0)
 | 
					 | 
				
			||||||
#define BF_ST_DIVIDE_ZERO (1 << 1)
 | 
					 | 
				
			||||||
#define BF_ST_OVERFLOW    (1 << 2)
 | 
					 | 
				
			||||||
#define BF_ST_UNDERFLOW   (1 << 3)
 | 
					 | 
				
			||||||
#define BF_ST_INEXACT     (1 << 4)
 | 
					 | 
				
			||||||
/* indicate that a memory allocation error occured. NaN is returned */
 | 
					 | 
				
			||||||
#define BF_ST_MEM_ERROR   (1 << 5)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define BF_RADIX_MAX 36 /* maximum radix for bf_atof() and bf_ftoa() */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline slimb_t bf_max(slimb_t a, slimb_t b)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if (a > b)
 | 
					 | 
				
			||||||
        return a;
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
        return b;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline slimb_t bf_min(slimb_t a, slimb_t b)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if (a < b)
 | 
					 | 
				
			||||||
        return a;
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
        return b;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void bf_context_init(bf_context_t *s, bf_realloc_func_t *realloc_func,
 | 
					 | 
				
			||||||
                     void *realloc_opaque);
 | 
					 | 
				
			||||||
void bf_context_end(bf_context_t *s);
 | 
					 | 
				
			||||||
/* free memory allocated for the bf cache data */
 | 
					 | 
				
			||||||
void bf_clear_cache(bf_context_t *s);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline void *bf_realloc(bf_context_t *s, void *ptr, size_t size)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return s->realloc_func(s->realloc_opaque, ptr, size);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* 'size' must be != 0 */
 | 
					 | 
				
			||||||
static inline void *bf_malloc(bf_context_t *s, size_t size)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return bf_realloc(s, NULL, size);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline void bf_free(bf_context_t *s, void *ptr)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    /* must test ptr otherwise equivalent to malloc(0) */
 | 
					 | 
				
			||||||
    if (ptr)
 | 
					 | 
				
			||||||
        bf_realloc(s, ptr, 0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void bf_init(bf_context_t *s, bf_t *r);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline void bf_delete(bf_t *r)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    bf_context_t *s = r->ctx;
 | 
					 | 
				
			||||||
    /* we accept to delete a zeroed bf_t structure */
 | 
					 | 
				
			||||||
    if (s && r->tab) {
 | 
					 | 
				
			||||||
        bf_realloc(s, r->tab, 0);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline void bf_neg(bf_t *r)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    r->sign ^= 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline int bf_is_finite(const bf_t *a)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return (a->expn < BF_EXP_INF);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline int bf_is_nan(const bf_t *a)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return (a->expn == BF_EXP_NAN);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline int bf_is_zero(const bf_t *a)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return (a->expn == BF_EXP_ZERO);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline void bf_memcpy(bf_t *r, const bf_t *a)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    *r = *a;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int bf_set_ui(bf_t *r, uint64_t a);
 | 
					 | 
				
			||||||
int bf_set_si(bf_t *r, int64_t a);
 | 
					 | 
				
			||||||
void bf_set_nan(bf_t *r);
 | 
					 | 
				
			||||||
void bf_set_zero(bf_t *r, int is_neg);
 | 
					 | 
				
			||||||
void bf_set_inf(bf_t *r, int is_neg);
 | 
					 | 
				
			||||||
int bf_set(bf_t *r, const bf_t *a);
 | 
					 | 
				
			||||||
void bf_move(bf_t *r, bf_t *a);
 | 
					 | 
				
			||||||
int bf_get_float64(const bf_t *a, double *pres, bf_rnd_t rnd_mode);
 | 
					 | 
				
			||||||
int bf_set_float64(bf_t *a, double d);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int bf_cmpu(const bf_t *a, const bf_t *b);
 | 
					 | 
				
			||||||
int bf_cmp_full(const bf_t *a, const bf_t *b);
 | 
					 | 
				
			||||||
int bf_cmp(const bf_t *a, const bf_t *b);
 | 
					 | 
				
			||||||
static inline int bf_cmp_eq(const bf_t *a, const bf_t *b)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return bf_cmp(a, b) == 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline int bf_cmp_le(const bf_t *a, const bf_t *b)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return bf_cmp(a, b) <= 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline int bf_cmp_lt(const bf_t *a, const bf_t *b)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return bf_cmp(a, b) < 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int bf_add(bf_t *r, const bf_t *a, const bf_t *b, limb_t prec, bf_flags_t flags);
 | 
					 | 
				
			||||||
int bf_sub(bf_t *r, const bf_t *a, const bf_t *b, limb_t prec, bf_flags_t flags);
 | 
					 | 
				
			||||||
int bf_add_si(bf_t *r, const bf_t *a, int64_t b1, limb_t prec, bf_flags_t flags);
 | 
					 | 
				
			||||||
int bf_mul(bf_t *r, const bf_t *a, const bf_t *b, limb_t prec, bf_flags_t flags);
 | 
					 | 
				
			||||||
int bf_mul_ui(bf_t *r, const bf_t *a, uint64_t b1, limb_t prec, bf_flags_t flags);
 | 
					 | 
				
			||||||
int bf_mul_si(bf_t *r, const bf_t *a, int64_t b1, limb_t prec,
 | 
					 | 
				
			||||||
              bf_flags_t flags);
 | 
					 | 
				
			||||||
int bf_mul_2exp(bf_t *r, slimb_t e, limb_t prec, bf_flags_t flags);
 | 
					 | 
				
			||||||
int bf_div(bf_t *r, const bf_t *a, const bf_t *b, limb_t prec, bf_flags_t flags);
 | 
					 | 
				
			||||||
#define BF_DIVREM_EUCLIDIAN BF_RNDF
 | 
					 | 
				
			||||||
int bf_divrem(bf_t *q, bf_t *r, const bf_t *a, const bf_t *b,
 | 
					 | 
				
			||||||
              limb_t prec, bf_flags_t flags, int rnd_mode);
 | 
					 | 
				
			||||||
int bf_rem(bf_t *r, const bf_t *a, const bf_t *b, limb_t prec,
 | 
					 | 
				
			||||||
           bf_flags_t flags, int rnd_mode);
 | 
					 | 
				
			||||||
int bf_remquo(slimb_t *pq, bf_t *r, const bf_t *a, const bf_t *b, limb_t prec,
 | 
					 | 
				
			||||||
              bf_flags_t flags, int rnd_mode);
 | 
					 | 
				
			||||||
/* round to integer with infinite precision */
 | 
					 | 
				
			||||||
int bf_rint(bf_t *r, int rnd_mode);
 | 
					 | 
				
			||||||
int bf_round(bf_t *r, limb_t prec, bf_flags_t flags);
 | 
					 | 
				
			||||||
int bf_sqrtrem(bf_t *r, bf_t *rem1, const bf_t *a);
 | 
					 | 
				
			||||||
int bf_sqrt(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags);
 | 
					 | 
				
			||||||
slimb_t bf_get_exp_min(const bf_t *a);
 | 
					 | 
				
			||||||
int bf_logic_or(bf_t *r, const bf_t *a, const bf_t *b);
 | 
					 | 
				
			||||||
int bf_logic_xor(bf_t *r, const bf_t *a, const bf_t *b);
 | 
					 | 
				
			||||||
int bf_logic_and(bf_t *r, const bf_t *a, const bf_t *b);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* additional flags for bf_atof */
 | 
					 | 
				
			||||||
/* do not accept hex radix prefix (0x or 0X) if radix = 0 or radix = 16 */
 | 
					 | 
				
			||||||
#define BF_ATOF_NO_HEX       (1 << 16)
 | 
					 | 
				
			||||||
/* accept binary (0b or 0B) or octal (0o or 0O) radix prefix if radix = 0 */
 | 
					 | 
				
			||||||
#define BF_ATOF_BIN_OCT      (1 << 17)
 | 
					 | 
				
			||||||
/* Do not parse NaN or Inf */
 | 
					 | 
				
			||||||
#define BF_ATOF_NO_NAN_INF   (1 << 18)
 | 
					 | 
				
			||||||
/* return the exponent separately */
 | 
					 | 
				
			||||||
#define BF_ATOF_EXPONENT       (1 << 19)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int bf_atof(bf_t *a, const char *str, const char **pnext, int radix,
 | 
					 | 
				
			||||||
            limb_t prec, bf_flags_t flags);
 | 
					 | 
				
			||||||
/* this version accepts prec = BF_PREC_INF and returns the radix
 | 
					 | 
				
			||||||
   exponent */
 | 
					 | 
				
			||||||
int bf_atof2(bf_t *r, slimb_t *pexponent,
 | 
					 | 
				
			||||||
             const char *str, const char **pnext, int radix,
 | 
					 | 
				
			||||||
             limb_t prec, bf_flags_t flags);
 | 
					 | 
				
			||||||
int bf_mul_pow_radix(bf_t *r, const bf_t *T, limb_t radix,
 | 
					 | 
				
			||||||
                     slimb_t expn, limb_t prec, bf_flags_t flags);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Conversion of floating point number to string. Return a null
 | 
					 | 
				
			||||||
   terminated string or NULL if memory error. *plen contains its
 | 
					 | 
				
			||||||
   length if plen != NULL.  The exponent letter is "e" for base 10,
 | 
					 | 
				
			||||||
   "p" for bases 2, 8, 16 with a binary exponent and "@" for the other
 | 
					 | 
				
			||||||
   bases. */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define BF_FTOA_FORMAT_MASK (3 << 16)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* fixed format: prec significant digits rounded with (flags &
 | 
					 | 
				
			||||||
   BF_RND_MASK). Exponential notation is used if too many zeros are
 | 
					 | 
				
			||||||
   needed.*/
 | 
					 | 
				
			||||||
#define BF_FTOA_FORMAT_FIXED (0 << 16)
 | 
					 | 
				
			||||||
/* fractional format: prec digits after the decimal point rounded with
 | 
					 | 
				
			||||||
   (flags & BF_RND_MASK) */
 | 
					 | 
				
			||||||
#define BF_FTOA_FORMAT_FRAC  (1 << 16)
 | 
					 | 
				
			||||||
/* free format:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   For binary radices with bf_ftoa() and for bfdec_ftoa(): use the minimum
 | 
					 | 
				
			||||||
   number of digits to represent 'a'. The precision and the rounding
 | 
					 | 
				
			||||||
   mode are ignored.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   For the non binary radices with bf_ftoa(): use as many digits as
 | 
					 | 
				
			||||||
   necessary so that bf_atof() return the same number when using
 | 
					 | 
				
			||||||
   precision 'prec', rounding to nearest and the subnormal
 | 
					 | 
				
			||||||
   configuration of 'flags'. The result is meaningful only if 'a' is
 | 
					 | 
				
			||||||
   already rounded to 'prec' bits. If the subnormal flag is set, the
 | 
					 | 
				
			||||||
   exponent in 'flags' must also be set to the desired exponent range.
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
#define BF_FTOA_FORMAT_FREE  (2 << 16)
 | 
					 | 
				
			||||||
/* same as BF_FTOA_FORMAT_FREE but uses the minimum number of digits
 | 
					 | 
				
			||||||
   (takes more computation time). Identical to BF_FTOA_FORMAT_FREE for
 | 
					 | 
				
			||||||
   binary radices with bf_ftoa() and for bfdec_ftoa(). */
 | 
					 | 
				
			||||||
#define BF_FTOA_FORMAT_FREE_MIN (3 << 16)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* force exponential notation for fixed or free format */
 | 
					 | 
				
			||||||
#define BF_FTOA_FORCE_EXP    (1 << 20)
 | 
					 | 
				
			||||||
/* add 0x prefix for base 16, 0o prefix for base 8 or 0b prefix for
 | 
					 | 
				
			||||||
   base 2 if non zero value */
 | 
					 | 
				
			||||||
#define BF_FTOA_ADD_PREFIX   (1 << 21)
 | 
					 | 
				
			||||||
/* return "Infinity" instead of "Inf" and add a "+" for positive
 | 
					 | 
				
			||||||
   exponents */
 | 
					 | 
				
			||||||
#define BF_FTOA_JS_QUIRKS    (1 << 22)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
char *bf_ftoa(size_t *plen, const bf_t *a, int radix, limb_t prec,
 | 
					 | 
				
			||||||
              bf_flags_t flags);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* modulo 2^n instead of saturation. NaN and infinity return 0 */
 | 
					 | 
				
			||||||
#define BF_GET_INT_MOD (1 << 0)
 | 
					 | 
				
			||||||
int bf_get_int32(int *pres, const bf_t *a, int flags);
 | 
					 | 
				
			||||||
int bf_get_int64(int64_t *pres, const bf_t *a, int flags);
 | 
					 | 
				
			||||||
int bf_get_uint64(uint64_t *pres, const bf_t *a);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* the following functions are exported for testing only. */
 | 
					 | 
				
			||||||
void mp_print_str(const char *str, const limb_t *tab, limb_t n);
 | 
					 | 
				
			||||||
void bf_print_str(const char *str, const bf_t *a);
 | 
					 | 
				
			||||||
int bf_resize(bf_t *r, limb_t len);
 | 
					 | 
				
			||||||
int bf_get_fft_size(int *pdpl, int *pnb_mods, limb_t len);
 | 
					 | 
				
			||||||
int bf_normalize_and_round(bf_t *r, limb_t prec1, bf_flags_t flags);
 | 
					 | 
				
			||||||
int bf_can_round(const bf_t *a, slimb_t prec, bf_rnd_t rnd_mode, slimb_t k);
 | 
					 | 
				
			||||||
slimb_t bf_mul_log2_radix(slimb_t a1, unsigned int radix, int is_inv,
 | 
					 | 
				
			||||||
                          int is_ceil1);
 | 
					 | 
				
			||||||
int mp_mul(bf_context_t *s, limb_t *result,
 | 
					 | 
				
			||||||
           const limb_t *op1, limb_t op1_size,
 | 
					 | 
				
			||||||
           const limb_t *op2, limb_t op2_size);
 | 
					 | 
				
			||||||
limb_t mp_add(limb_t *res, const limb_t *op1, const limb_t *op2,
 | 
					 | 
				
			||||||
              limb_t n, limb_t carry);
 | 
					 | 
				
			||||||
limb_t mp_add_ui(limb_t *tab, limb_t b, size_t n);
 | 
					 | 
				
			||||||
int mp_sqrtrem(bf_context_t *s, limb_t *tabs, limb_t *taba, limb_t n);
 | 
					 | 
				
			||||||
int mp_recip(bf_context_t *s, limb_t *tabr, const limb_t *taba, limb_t n);
 | 
					 | 
				
			||||||
limb_t bf_isqrt(limb_t a);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* transcendental functions */
 | 
					 | 
				
			||||||
int bf_const_log2(bf_t *T, limb_t prec, bf_flags_t flags);
 | 
					 | 
				
			||||||
int bf_const_pi(bf_t *T, limb_t prec, bf_flags_t flags);
 | 
					 | 
				
			||||||
int bf_exp(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags);
 | 
					 | 
				
			||||||
int bf_log(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags);
 | 
					 | 
				
			||||||
#define BF_POW_JS_QUIRKS (1 << 16) /* (+/-1)^(+/-Inf) = NaN, 1^NaN = NaN */
 | 
					 | 
				
			||||||
int bf_pow(bf_t *r, const bf_t *x, const bf_t *y, limb_t prec, bf_flags_t flags);
 | 
					 | 
				
			||||||
int bf_cos(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags);
 | 
					 | 
				
			||||||
int bf_sin(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags);
 | 
					 | 
				
			||||||
int bf_tan(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags);
 | 
					 | 
				
			||||||
int bf_atan(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags);
 | 
					 | 
				
			||||||
int bf_atan2(bf_t *r, const bf_t *y, const bf_t *x,
 | 
					 | 
				
			||||||
             limb_t prec, bf_flags_t flags);
 | 
					 | 
				
			||||||
int bf_asin(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags);
 | 
					 | 
				
			||||||
int bf_acos(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* decimal floating point */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline void bfdec_init(bf_context_t *s, bfdec_t *r)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    bf_init(s, (bf_t *)r);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
static inline void bfdec_delete(bfdec_t *r)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    bf_delete((bf_t *)r);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline void bfdec_neg(bfdec_t *r)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    r->sign ^= 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline int bfdec_is_finite(const bfdec_t *a)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return (a->expn < BF_EXP_INF);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline int bfdec_is_nan(const bfdec_t *a)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return (a->expn == BF_EXP_NAN);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline int bfdec_is_zero(const bfdec_t *a)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return (a->expn == BF_EXP_ZERO);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline void bfdec_memcpy(bfdec_t *r, const bfdec_t *a)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    bf_memcpy((bf_t *)r, (const bf_t *)a);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int bfdec_set_ui(bfdec_t *r, uint64_t a);
 | 
					 | 
				
			||||||
int bfdec_set_si(bfdec_t *r, int64_t a);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline void bfdec_set_nan(bfdec_t *r)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    bf_set_nan((bf_t *)r);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
static inline void bfdec_set_zero(bfdec_t *r, int is_neg)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    bf_set_zero((bf_t *)r, is_neg);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
static inline void bfdec_set_inf(bfdec_t *r, int is_neg)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    bf_set_inf((bf_t *)r, is_neg);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
static inline int bfdec_set(bfdec_t *r, const bfdec_t *a)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return bf_set((bf_t *)r, (bf_t *)a);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
static inline void bfdec_move(bfdec_t *r, bfdec_t *a)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    bf_move((bf_t *)r, (bf_t *)a);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
static inline int bfdec_cmpu(const bfdec_t *a, const bfdec_t *b)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return bf_cmpu((const bf_t *)a, (const bf_t *)b);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
static inline int bfdec_cmp_full(const bfdec_t *a, const bfdec_t *b)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return bf_cmp_full((const bf_t *)a, (const bf_t *)b);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
static inline int bfdec_cmp(const bfdec_t *a, const bfdec_t *b)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return bf_cmp((const bf_t *)a, (const bf_t *)b);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
static inline int bfdec_cmp_eq(const bfdec_t *a, const bfdec_t *b)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return bfdec_cmp(a, b) == 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
static inline int bfdec_cmp_le(const bfdec_t *a, const bfdec_t *b)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return bfdec_cmp(a, b) <= 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
static inline int bfdec_cmp_lt(const bfdec_t *a, const bfdec_t *b)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return bfdec_cmp(a, b) < 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int bfdec_add(bfdec_t *r, const bfdec_t *a, const bfdec_t *b, limb_t prec,
 | 
					 | 
				
			||||||
              bf_flags_t flags);
 | 
					 | 
				
			||||||
int bfdec_sub(bfdec_t *r, const bfdec_t *a, const bfdec_t *b, limb_t prec,
 | 
					 | 
				
			||||||
              bf_flags_t flags);
 | 
					 | 
				
			||||||
int bfdec_add_si(bfdec_t *r, const bfdec_t *a, int64_t b1, limb_t prec,
 | 
					 | 
				
			||||||
                 bf_flags_t flags);
 | 
					 | 
				
			||||||
int bfdec_mul(bfdec_t *r, const bfdec_t *a, const bfdec_t *b, limb_t prec,
 | 
					 | 
				
			||||||
              bf_flags_t flags);
 | 
					 | 
				
			||||||
int bfdec_mul_si(bfdec_t *r, const bfdec_t *a, int64_t b1, limb_t prec,
 | 
					 | 
				
			||||||
                 bf_flags_t flags);
 | 
					 | 
				
			||||||
int bfdec_div(bfdec_t *r, const bfdec_t *a, const bfdec_t *b, limb_t prec,
 | 
					 | 
				
			||||||
              bf_flags_t flags);
 | 
					 | 
				
			||||||
int bfdec_divrem(bfdec_t *q, bfdec_t *r, const bfdec_t *a, const bfdec_t *b,
 | 
					 | 
				
			||||||
                 limb_t prec, bf_flags_t flags, int rnd_mode);
 | 
					 | 
				
			||||||
int bfdec_rem(bfdec_t *r, const bfdec_t *a, const bfdec_t *b, limb_t prec,
 | 
					 | 
				
			||||||
              bf_flags_t flags, int rnd_mode);
 | 
					 | 
				
			||||||
int bfdec_rint(bfdec_t *r, int rnd_mode);
 | 
					 | 
				
			||||||
int bfdec_sqrt(bfdec_t *r, const bfdec_t *a, limb_t prec, bf_flags_t flags);
 | 
					 | 
				
			||||||
int bfdec_round(bfdec_t *r, limb_t prec, bf_flags_t flags);
 | 
					 | 
				
			||||||
int bfdec_get_int32(int *pres, const bfdec_t *a);
 | 
					 | 
				
			||||||
int bfdec_pow_ui(bfdec_t *r, const bfdec_t *a, limb_t b);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
char *bfdec_ftoa(size_t *plen, const bfdec_t *a, limb_t prec, bf_flags_t flags);
 | 
					 | 
				
			||||||
int bfdec_atof(bfdec_t *r, const char *str, const char **pnext,
 | 
					 | 
				
			||||||
               limb_t prec, bf_flags_t flags);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* the following functions are exported for testing only. */
 | 
					 | 
				
			||||||
extern const limb_t mp_pow_dec[LIMB_DIGITS + 1];
 | 
					 | 
				
			||||||
void bfdec_print_str(const char *str, const bfdec_t *a);
 | 
					 | 
				
			||||||
static inline int bfdec_resize(bfdec_t *r, limb_t len)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return bf_resize((bf_t *)r, len);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
int bfdec_normalize_and_round(bfdec_t *r, limb_t prec1, bf_flags_t flags);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif /* LIBBF_H */
 | 
					 | 
				
			||||||
							
								
								
									
										52
									
								
								qjs.c
									
									
									
									
									
								
							
							
						
						
									
										52
									
								
								qjs.c
									
									
									
									
									
								
							@ -45,11 +45,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
extern const uint8_t qjsc_repl[];
 | 
					extern const uint8_t qjsc_repl[];
 | 
				
			||||||
extern const uint32_t qjsc_repl_size;
 | 
					extern const uint32_t qjsc_repl_size;
 | 
				
			||||||
#ifdef CONFIG_BIGNUM
 | 
					 | 
				
			||||||
extern const uint8_t qjsc_qjscalc[];
 | 
					 | 
				
			||||||
extern const uint32_t qjsc_qjscalc_size;
 | 
					 | 
				
			||||||
static int bignum_ext;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int eval_buf(JSContext *ctx, const void *buf, int buf_len,
 | 
					static int eval_buf(JSContext *ctx, const void *buf, int buf_len,
 | 
				
			||||||
                    const char *filename, int eval_flags)
 | 
					                    const char *filename, int eval_flags)
 | 
				
			||||||
@ -112,14 +107,6 @@ static JSContext *JS_NewCustomContext(JSRuntime *rt)
 | 
				
			|||||||
    ctx = JS_NewContext(rt);
 | 
					    ctx = JS_NewContext(rt);
 | 
				
			||||||
    if (!ctx)
 | 
					    if (!ctx)
 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
#ifdef CONFIG_BIGNUM
 | 
					 | 
				
			||||||
    if (bignum_ext) {
 | 
					 | 
				
			||||||
        JS_AddIntrinsicBigFloat(ctx);
 | 
					 | 
				
			||||||
        JS_AddIntrinsicBigDecimal(ctx);
 | 
					 | 
				
			||||||
        JS_AddIntrinsicOperators(ctx);
 | 
					 | 
				
			||||||
        JS_EnableBignumExt(ctx, TRUE);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    /* system modules */
 | 
					    /* system modules */
 | 
				
			||||||
    js_init_module_std(ctx, "std");
 | 
					    js_init_module_std(ctx, "std");
 | 
				
			||||||
    js_init_module_os(ctx, "os");
 | 
					    js_init_module_os(ctx, "os");
 | 
				
			||||||
@ -283,10 +270,6 @@ void help(void)
 | 
				
			|||||||
           "    --script       load as ES6 script (default=autodetect)\n"
 | 
					           "    --script       load as ES6 script (default=autodetect)\n"
 | 
				
			||||||
           "-I  --include file include an additional file\n"
 | 
					           "-I  --include file include an additional file\n"
 | 
				
			||||||
           "    --std          make 'std' and 'os' available to the loaded script\n"
 | 
					           "    --std          make 'std' and 'os' available to the loaded script\n"
 | 
				
			||||||
#ifdef CONFIG_BIGNUM
 | 
					 | 
				
			||||||
           "    --bignum       enable the bignum extensions (BigFloat, BigDecimal)\n"
 | 
					 | 
				
			||||||
           "    --qjscalc      load the QJSCalc runtime (default if invoked as qjscalc)\n"
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
           "-T  --trace        trace memory allocation\n"
 | 
					           "-T  --trace        trace memory allocation\n"
 | 
				
			||||||
           "-d  --dump         dump the memory usage stats\n"
 | 
					           "-d  --dump         dump the memory usage stats\n"
 | 
				
			||||||
           "    --memory-limit n       limit the memory usage to 'n' bytes\n"
 | 
					           "    --memory-limit n       limit the memory usage to 'n' bytes\n"
 | 
				
			||||||
@ -313,23 +296,8 @@ int main(int argc, char **argv)
 | 
				
			|||||||
    size_t memory_limit = 0;
 | 
					    size_t memory_limit = 0;
 | 
				
			||||||
    char *include_list[32];
 | 
					    char *include_list[32];
 | 
				
			||||||
    int i, include_count = 0;
 | 
					    int i, include_count = 0;
 | 
				
			||||||
#ifdef CONFIG_BIGNUM
 | 
					 | 
				
			||||||
    int load_jscalc;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    size_t stack_size = 0;
 | 
					    size_t stack_size = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_BIGNUM
 | 
					 | 
				
			||||||
    /* load jscalc runtime if invoked as 'qjscalc' */
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        const char *p, *exename;
 | 
					 | 
				
			||||||
        exename = argv[0];
 | 
					 | 
				
			||||||
        p = strrchr(exename, '/');
 | 
					 | 
				
			||||||
        if (p)
 | 
					 | 
				
			||||||
            exename = p + 1;
 | 
					 | 
				
			||||||
        load_jscalc = !strcmp(exename, "qjscalc");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* cannot use getopt because we want to pass the command line to
 | 
					    /* cannot use getopt because we want to pass the command line to
 | 
				
			||||||
       the script */
 | 
					       the script */
 | 
				
			||||||
    optind = 1;
 | 
					    optind = 1;
 | 
				
			||||||
@ -407,16 +375,6 @@ int main(int argc, char **argv)
 | 
				
			|||||||
                dump_unhandled_promise_rejection = 1;
 | 
					                dump_unhandled_promise_rejection = 1;
 | 
				
			||||||
                continue;
 | 
					                continue;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
#ifdef CONFIG_BIGNUM
 | 
					 | 
				
			||||||
            if (!strcmp(longopt, "bignum")) {
 | 
					 | 
				
			||||||
                bignum_ext = 1;
 | 
					 | 
				
			||||||
                continue;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            if (!strcmp(longopt, "qjscalc")) {
 | 
					 | 
				
			||||||
                load_jscalc = 1;
 | 
					 | 
				
			||||||
                continue;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
            if (opt == 'q' || !strcmp(longopt, "quit")) {
 | 
					            if (opt == 'q' || !strcmp(longopt, "quit")) {
 | 
				
			||||||
                empty_run++;
 | 
					                empty_run++;
 | 
				
			||||||
                continue;
 | 
					                continue;
 | 
				
			||||||
@ -446,11 +404,6 @@ int main(int argc, char **argv)
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_BIGNUM
 | 
					 | 
				
			||||||
    if (load_jscalc)
 | 
					 | 
				
			||||||
        bignum_ext = 1;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (trace_memory) {
 | 
					    if (trace_memory) {
 | 
				
			||||||
        js_trace_malloc_init(&trace_data);
 | 
					        js_trace_malloc_init(&trace_data);
 | 
				
			||||||
        rt = JS_NewRuntime2(&trace_mf, &trace_data);
 | 
					        rt = JS_NewRuntime2(&trace_mf, &trace_data);
 | 
				
			||||||
@ -482,11 +435,6 @@ int main(int argc, char **argv)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!empty_run) {
 | 
					    if (!empty_run) {
 | 
				
			||||||
#ifdef CONFIG_BIGNUM
 | 
					 | 
				
			||||||
        if (load_jscalc) {
 | 
					 | 
				
			||||||
            js_std_eval_binary(ctx, qjsc_qjscalc, qjsc_qjscalc_size, 0);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
        js_std_add_helpers(ctx, argc - optind, argv + optind);
 | 
					        js_std_add_helpers(ctx, argc - optind, argv + optind);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* make 'std' and 'os' visible to non module code */
 | 
					        /* make 'std' and 'os' visible to non module code */
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										28
									
								
								qjsc.c
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								qjsc.c
									
									
									
									
									
								
							@ -492,9 +492,6 @@ int main(int argc, char **argv)
 | 
				
			|||||||
    int module;
 | 
					    int module;
 | 
				
			||||||
    OutputTypeEnum output_type;
 | 
					    OutputTypeEnum output_type;
 | 
				
			||||||
    size_t stack_size;
 | 
					    size_t stack_size;
 | 
				
			||||||
#ifdef CONFIG_BIGNUM
 | 
					 | 
				
			||||||
    BOOL bignum_ext = FALSE;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    namelist_t dynamic_module_list;
 | 
					    namelist_t dynamic_module_list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    out_filename = NULL;
 | 
					    out_filename = NULL;
 | 
				
			||||||
@ -547,13 +544,7 @@ int main(int argc, char **argv)
 | 
				
			|||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    if (i == countof(feature_list))
 | 
					                    if (i == countof(feature_list))
 | 
				
			||||||
                        goto bad_feature;
 | 
					                        goto bad_feature;
 | 
				
			||||||
                } else
 | 
					                } else {
 | 
				
			||||||
#ifdef CONFIG_BIGNUM
 | 
					 | 
				
			||||||
                if (!strcmp(optarg, "bignum")) {
 | 
					 | 
				
			||||||
                    bignum_ext = TRUE;
 | 
					 | 
				
			||||||
                } else
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                bad_feature:
 | 
					                bad_feature:
 | 
				
			||||||
                    fprintf(stderr, "unsupported feature: %s\n", optarg);
 | 
					                    fprintf(stderr, "unsupported feature: %s\n", optarg);
 | 
				
			||||||
                    exit(1);
 | 
					                    exit(1);
 | 
				
			||||||
@ -630,14 +621,6 @@ int main(int argc, char **argv)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    rt = JS_NewRuntime();
 | 
					    rt = JS_NewRuntime();
 | 
				
			||||||
    ctx = JS_NewContext(rt);
 | 
					    ctx = JS_NewContext(rt);
 | 
				
			||||||
#ifdef CONFIG_BIGNUM
 | 
					 | 
				
			||||||
    if (bignum_ext) {
 | 
					 | 
				
			||||||
        JS_AddIntrinsicBigFloat(ctx);
 | 
					 | 
				
			||||||
        JS_AddIntrinsicBigDecimal(ctx);
 | 
					 | 
				
			||||||
        JS_AddIntrinsicOperators(ctx);
 | 
					 | 
				
			||||||
        JS_EnableBignumExt(ctx, TRUE);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* loader for ES6 modules */
 | 
					    /* loader for ES6 modules */
 | 
				
			||||||
    JS_SetModuleLoaderFunc(rt, NULL, jsc_module_loader, NULL);
 | 
					    JS_SetModuleLoaderFunc(rt, NULL, jsc_module_loader, NULL);
 | 
				
			||||||
@ -686,15 +669,6 @@ int main(int argc, char **argv)
 | 
				
			|||||||
                        feature_list[i].init_name);
 | 
					                        feature_list[i].init_name);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
#ifdef CONFIG_BIGNUM
 | 
					 | 
				
			||||||
        if (bignum_ext) {
 | 
					 | 
				
			||||||
            fprintf(fo,
 | 
					 | 
				
			||||||
                    "  JS_AddIntrinsicBigFloat(ctx);\n"
 | 
					 | 
				
			||||||
                    "  JS_AddIntrinsicBigDecimal(ctx);\n"
 | 
					 | 
				
			||||||
                    "  JS_AddIntrinsicOperators(ctx);\n"
 | 
					 | 
				
			||||||
                    "  JS_EnableBignumExt(ctx, 1);\n");
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
        /* add the precompiled modules (XXX: could modify the module
 | 
					        /* add the precompiled modules (XXX: could modify the module
 | 
				
			||||||
           loader instead) */
 | 
					           loader instead) */
 | 
				
			||||||
        for(i = 0; i < init_module_list.count; i++) {
 | 
					        for(i = 0; i < init_module_list.count; i++) {
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										2657
									
								
								qjscalc.js
									
									
									
									
									
								
							
							
						
						
									
										2657
									
								
								qjscalc.js
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -172,13 +172,6 @@ DEF(status, "status")
 | 
				
			|||||||
DEF(reason, "reason")
 | 
					DEF(reason, "reason")
 | 
				
			||||||
DEF(globalThis, "globalThis")
 | 
					DEF(globalThis, "globalThis")
 | 
				
			||||||
DEF(bigint, "bigint")
 | 
					DEF(bigint, "bigint")
 | 
				
			||||||
#ifdef CONFIG_BIGNUM
 | 
					 | 
				
			||||||
DEF(bigfloat, "bigfloat")
 | 
					 | 
				
			||||||
DEF(bigdecimal, "bigdecimal")
 | 
					 | 
				
			||||||
DEF(roundingMode, "roundingMode")
 | 
					 | 
				
			||||||
DEF(maximumSignificantDigits, "maximumSignificantDigits")
 | 
					 | 
				
			||||||
DEF(maximumFractionDigits, "maximumFractionDigits")
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
/* the following 3 atoms are only used with CONFIG_ATOMICS */
 | 
					/* the following 3 atoms are only used with CONFIG_ATOMICS */
 | 
				
			||||||
DEF(not_equal, "not-equal")
 | 
					DEF(not_equal, "not-equal")
 | 
				
			||||||
DEF(timed_out, "timed-out")
 | 
					DEF(timed_out, "timed-out")
 | 
				
			||||||
@ -217,13 +210,6 @@ DEF(Float32Array, "Float32Array")
 | 
				
			|||||||
DEF(Float64Array, "Float64Array")
 | 
					DEF(Float64Array, "Float64Array")
 | 
				
			||||||
DEF(DataView, "DataView")
 | 
					DEF(DataView, "DataView")
 | 
				
			||||||
DEF(BigInt, "BigInt")
 | 
					DEF(BigInt, "BigInt")
 | 
				
			||||||
#ifdef CONFIG_BIGNUM
 | 
					 | 
				
			||||||
DEF(BigFloat, "BigFloat")
 | 
					 | 
				
			||||||
DEF(BigFloatEnv, "BigFloatEnv")
 | 
					 | 
				
			||||||
DEF(BigDecimal, "BigDecimal")
 | 
					 | 
				
			||||||
DEF(OperatorSet, "OperatorSet")
 | 
					 | 
				
			||||||
DEF(Operators, "Operators")
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
DEF(Map, "Map")
 | 
					DEF(Map, "Map")
 | 
				
			||||||
DEF(Set, "Set") /* Map + 1 */
 | 
					DEF(Set, "Set") /* Map + 1 */
 | 
				
			||||||
DEF(WeakMap, "WeakMap") /* Map + 2 */
 | 
					DEF(WeakMap, "WeakMap") /* Map + 2 */
 | 
				
			||||||
@ -266,8 +252,5 @@ DEF(Symbol_hasInstance, "Symbol.hasInstance")
 | 
				
			|||||||
DEF(Symbol_species, "Symbol.species")
 | 
					DEF(Symbol_species, "Symbol.species")
 | 
				
			||||||
DEF(Symbol_unscopables, "Symbol.unscopables")
 | 
					DEF(Symbol_unscopables, "Symbol.unscopables")
 | 
				
			||||||
DEF(Symbol_asyncIterator, "Symbol.asyncIterator")
 | 
					DEF(Symbol_asyncIterator, "Symbol.asyncIterator")
 | 
				
			||||||
#ifdef CONFIG_BIGNUM
 | 
					 | 
				
			||||||
DEF(Symbol_operatorSet, "Symbol.operatorSet")
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* DEF */
 | 
					#endif /* DEF */
 | 
				
			||||||
 | 
				
			|||||||
@ -258,10 +258,7 @@ 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)
 | 
				
			||||||
DEF(     private_in, 1, 2, 1, none)
 | 
					DEF(     private_in, 1, 2, 1, none)
 | 
				
			||||||
#ifdef CONFIG_BIGNUM
 | 
					DEF(push_bigint_i32, 5, 0, 1, i32)
 | 
				
			||||||
DEF(      mul_pow10, 1, 2, 1, none)
 | 
					 | 
				
			||||||
DEF(       math_mod, 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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										39
									
								
								quickjs.h
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								quickjs.h
									
									
									
									
									
								
							@ -64,6 +64,14 @@ typedef uint32_t JSAtom;
 | 
				
			|||||||
#define JS_NAN_BOXING
 | 
					#define JS_NAN_BOXING
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(__SIZEOF_INT128__) && (INTPTR_MAX >= INT64_MAX)
 | 
				
			||||||
 | 
					#define JS_LIMB_BITS 64
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define JS_LIMB_BITS 32
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define JS_SHORT_BIG_INT_BITS JS_LIMB_BITS
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
enum {
 | 
					enum {
 | 
				
			||||||
    /* all tags with a reference count are negative */
 | 
					    /* all tags with a reference count are negative */
 | 
				
			||||||
    JS_TAG_FIRST       = -11, /* first negative tag */
 | 
					    JS_TAG_FIRST       = -11, /* first negative tag */
 | 
				
			||||||
@ -83,7 +91,8 @@ enum {
 | 
				
			|||||||
    JS_TAG_UNINITIALIZED = 4,
 | 
					    JS_TAG_UNINITIALIZED = 4,
 | 
				
			||||||
    JS_TAG_CATCH_OFFSET = 5,
 | 
					    JS_TAG_CATCH_OFFSET = 5,
 | 
				
			||||||
    JS_TAG_EXCEPTION   = 6,
 | 
					    JS_TAG_EXCEPTION   = 6,
 | 
				
			||||||
    JS_TAG_FLOAT64     = 7,
 | 
					    JS_TAG_SHORT_BIG_INT = 7,
 | 
				
			||||||
 | 
					    JS_TAG_FLOAT64     = 8,
 | 
				
			||||||
    /* any larger tag is FLOAT64 if JS_NAN_BOXING */
 | 
					    /* any larger tag is FLOAT64 if JS_NAN_BOXING */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -108,6 +117,7 @@ typedef const struct __JSValue *JSValueConst;
 | 
				
			|||||||
#define JS_VALUE_GET_INT(v) (int)((intptr_t)(v) >> 4)
 | 
					#define JS_VALUE_GET_INT(v) (int)((intptr_t)(v) >> 4)
 | 
				
			||||||
#define JS_VALUE_GET_BOOL(v) JS_VALUE_GET_INT(v)
 | 
					#define JS_VALUE_GET_BOOL(v) JS_VALUE_GET_INT(v)
 | 
				
			||||||
#define JS_VALUE_GET_FLOAT64(v) (double)JS_VALUE_GET_INT(v)
 | 
					#define JS_VALUE_GET_FLOAT64(v) (double)JS_VALUE_GET_INT(v)
 | 
				
			||||||
 | 
					#define JS_VALUE_GET_SHORT_BIG_INT(v) JS_VALUE_GET_INT(v)
 | 
				
			||||||
#define JS_VALUE_GET_PTR(v) (void *)((intptr_t)(v) & ~0xf)
 | 
					#define JS_VALUE_GET_PTR(v) (void *)((intptr_t)(v) & ~0xf)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define JS_MKVAL(tag, val) (JSValue)(intptr_t)(((val) << 4) | (tag))
 | 
					#define JS_MKVAL(tag, val) (JSValue)(intptr_t)(((val) << 4) | (tag))
 | 
				
			||||||
@ -127,6 +137,11 @@ static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v)
 | 
				
			|||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline JSValue __JS_NewShortBigInt(JSContext *ctx, int32_t d)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return JS_MKVAL(JS_TAG_SHORT_BIG_INT, d);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#elif defined(JS_NAN_BOXING)
 | 
					#elif defined(JS_NAN_BOXING)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef uint64_t JSValue;
 | 
					typedef uint64_t JSValue;
 | 
				
			||||||
@ -136,6 +151,7 @@ typedef uint64_t JSValue;
 | 
				
			|||||||
#define JS_VALUE_GET_TAG(v) (int)((v) >> 32)
 | 
					#define JS_VALUE_GET_TAG(v) (int)((v) >> 32)
 | 
				
			||||||
#define JS_VALUE_GET_INT(v) (int)(v)
 | 
					#define JS_VALUE_GET_INT(v) (int)(v)
 | 
				
			||||||
#define JS_VALUE_GET_BOOL(v) (int)(v)
 | 
					#define JS_VALUE_GET_BOOL(v) (int)(v)
 | 
				
			||||||
 | 
					#define JS_VALUE_GET_SHORT_BIG_INT(v) (int)(v)
 | 
				
			||||||
#define JS_VALUE_GET_PTR(v) (void *)(intptr_t)(v)
 | 
					#define JS_VALUE_GET_PTR(v) (void *)(intptr_t)(v)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define JS_MKVAL(tag, val) (((uint64_t)(tag) << 32) | (uint32_t)(val))
 | 
					#define JS_MKVAL(tag, val) (((uint64_t)(tag) << 32) | (uint32_t)(val))
 | 
				
			||||||
@ -192,12 +208,22 @@ static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v)
 | 
				
			|||||||
    return tag == (JS_NAN >> 32);
 | 
					    return tag == (JS_NAN >> 32);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline JSValue __JS_NewShortBigInt(JSContext *ctx, int32_t d)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return JS_MKVAL(JS_TAG_SHORT_BIG_INT, d);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#else /* !JS_NAN_BOXING */
 | 
					#else /* !JS_NAN_BOXING */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef union JSValueUnion {
 | 
					typedef union JSValueUnion {
 | 
				
			||||||
    int32_t int32;
 | 
					    int32_t int32;
 | 
				
			||||||
    double float64;
 | 
					    double float64;
 | 
				
			||||||
    void *ptr;
 | 
					    void *ptr;
 | 
				
			||||||
 | 
					#if JS_SHORT_BIG_INT_BITS == 32
 | 
				
			||||||
 | 
					    int32_t short_big_int;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					    int64_t short_big_int;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
} JSValueUnion;
 | 
					} JSValueUnion;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct JSValue {
 | 
					typedef struct JSValue {
 | 
				
			||||||
@ -213,6 +239,7 @@ typedef struct JSValue {
 | 
				
			|||||||
#define JS_VALUE_GET_INT(v) ((v).u.int32)
 | 
					#define JS_VALUE_GET_INT(v) ((v).u.int32)
 | 
				
			||||||
#define JS_VALUE_GET_BOOL(v) ((v).u.int32)
 | 
					#define JS_VALUE_GET_BOOL(v) ((v).u.int32)
 | 
				
			||||||
#define JS_VALUE_GET_FLOAT64(v) ((v).u.float64)
 | 
					#define JS_VALUE_GET_FLOAT64(v) ((v).u.float64)
 | 
				
			||||||
 | 
					#define JS_VALUE_GET_SHORT_BIG_INT(v) ((v).u.short_big_int)
 | 
				
			||||||
#define JS_VALUE_GET_PTR(v) ((v).u.ptr)
 | 
					#define JS_VALUE_GET_PTR(v) ((v).u.ptr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define JS_MKVAL(tag, val) (JSValue){ (JSValueUnion){ .int32 = val }, tag }
 | 
					#define JS_MKVAL(tag, val) (JSValue){ (JSValueUnion){ .int32 = val }, tag }
 | 
				
			||||||
@ -242,6 +269,14 @@ static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v)
 | 
				
			|||||||
    return (u.u64 & 0x7fffffffffffffff) > 0x7ff0000000000000;
 | 
					    return (u.u64 & 0x7fffffffffffffff) > 0x7ff0000000000000;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline JSValue __JS_NewShortBigInt(JSContext *ctx, int64_t d)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    JSValue v;
 | 
				
			||||||
 | 
					    v.tag = JS_TAG_SHORT_BIG_INT;
 | 
				
			||||||
 | 
					    v.u.short_big_int = d;
 | 
				
			||||||
 | 
					    return v;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* !JS_NAN_BOXING */
 | 
					#endif /* !JS_NAN_BOXING */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define JS_VALUE_IS_BOTH_INT(v1, v2) ((JS_VALUE_GET_TAG(v1) | JS_VALUE_GET_TAG(v2)) == 0)
 | 
					#define JS_VALUE_IS_BOTH_INT(v1, v2) ((JS_VALUE_GET_TAG(v1) | JS_VALUE_GET_TAG(v2)) == 0)
 | 
				
			||||||
@ -576,7 +611,7 @@ static inline JS_BOOL JS_IsNumber(JSValueConst v)
 | 
				
			|||||||
static inline JS_BOOL JS_IsBigInt(JSContext *ctx, JSValueConst v)
 | 
					static inline JS_BOOL JS_IsBigInt(JSContext *ctx, JSValueConst v)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int tag = JS_VALUE_GET_TAG(v);
 | 
					    int tag = JS_VALUE_GET_TAG(v);
 | 
				
			||||||
    return tag == JS_TAG_BIG_INT;
 | 
					    return tag == JS_TAG_BIG_INT || tag == JS_TAG_SHORT_BIG_INT;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline JS_BOOL JS_IsBigFloat(JSValueConst v)
 | 
					static inline JS_BOOL JS_IsBigFloat(JSValueConst v)
 | 
				
			||||||
 | 
				
			|||||||
@ -687,29 +687,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;
 | 
				
			||||||
@ -728,6 +705,11 @@ function bigint_arith(n, bits)
 | 
				
			|||||||
    return n * 1000;
 | 
					    return n * 1000;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function bigint32_arith(n)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return bigint_arith(n, 32);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function bigint64_arith(n)
 | 
					function bigint64_arith(n)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return bigint_arith(n, 64);
 | 
					    return bigint_arith(n, 64);
 | 
				
			||||||
@ -1231,13 +1213,10 @@ function main(argc, argv, g)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    if (typeof BigInt === "function") {
 | 
					    if (typeof BigInt === "function") {
 | 
				
			||||||
        /* BigInt test */
 | 
					        /* BigInt test */
 | 
				
			||||||
 | 
					        test_list.push(bigint32_arith);
 | 
				
			||||||
        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);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    test_list.push(sort_bench);
 | 
					    test_list.push(sort_bench);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (i = 1; i < argc;) {
 | 
					    for (i = 1; i < argc;) {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,279 +0,0 @@
 | 
				
			|||||||
"use strict";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function assert(actual, expected, message) {
 | 
					 | 
				
			||||||
    if (arguments.length == 1)
 | 
					 | 
				
			||||||
        expected = true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (actual === expected)
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (actual !== null && expected !== null
 | 
					 | 
				
			||||||
    &&  typeof actual == 'object' && typeof expected == 'object'
 | 
					 | 
				
			||||||
    &&  actual.toString() === expected.toString())
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    throw Error("assertion failed: got |" + actual + "|" +
 | 
					 | 
				
			||||||
                ", expected |" + expected + "|" +
 | 
					 | 
				
			||||||
                (message ? " (" + message + ")" : ""));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function assertThrows(err, func)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    var ex;
 | 
					 | 
				
			||||||
    ex = false;
 | 
					 | 
				
			||||||
    try {
 | 
					 | 
				
			||||||
        func();
 | 
					 | 
				
			||||||
    } catch(e) {
 | 
					 | 
				
			||||||
        ex = true;
 | 
					 | 
				
			||||||
        assert(e instanceof err);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    assert(ex, true, "exception expected");
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// load more elaborate version of assert if available
 | 
					 | 
				
			||||||
try { __loadScript("test_assert.js"); } catch(e) {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*----------------*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* a must be < b */
 | 
					 | 
				
			||||||
function test_less(a, b)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    assert(a < b);
 | 
					 | 
				
			||||||
    assert(!(b < a));
 | 
					 | 
				
			||||||
    assert(a <= b);
 | 
					 | 
				
			||||||
    assert(!(b <= a));
 | 
					 | 
				
			||||||
    assert(b > a);
 | 
					 | 
				
			||||||
    assert(!(a > b));
 | 
					 | 
				
			||||||
    assert(b >= a);
 | 
					 | 
				
			||||||
    assert(!(a >= b));
 | 
					 | 
				
			||||||
    assert(a != b);
 | 
					 | 
				
			||||||
    assert(!(a == b));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* a must be numerically equal to b */
 | 
					 | 
				
			||||||
function test_eq(a, b)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    assert(a == b);
 | 
					 | 
				
			||||||
    assert(b == a);
 | 
					 | 
				
			||||||
    assert(!(a != b));
 | 
					 | 
				
			||||||
    assert(!(b != a));
 | 
					 | 
				
			||||||
    assert(a <= b);
 | 
					 | 
				
			||||||
    assert(b <= a);
 | 
					 | 
				
			||||||
    assert(!(a < b));
 | 
					 | 
				
			||||||
    assert(a >= b);
 | 
					 | 
				
			||||||
    assert(b >= a);
 | 
					 | 
				
			||||||
    assert(!(a > b));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function test_divrem(div1, a, b, q)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    var div, divrem, t;
 | 
					 | 
				
			||||||
    div = BigInt[div1];
 | 
					 | 
				
			||||||
    divrem = BigInt[div1 + "rem"];
 | 
					 | 
				
			||||||
    assert(div(a, b) == q);
 | 
					 | 
				
			||||||
    t = divrem(a, b);
 | 
					 | 
				
			||||||
    assert(t[0] == q);
 | 
					 | 
				
			||||||
    assert(a == b * q + t[1]);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function test_idiv1(div, a, b, r)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    test_divrem(div, a, b, r[0]);
 | 
					 | 
				
			||||||
    test_divrem(div, -a, b, r[1]);
 | 
					 | 
				
			||||||
    test_divrem(div, a, -b, r[2]);
 | 
					 | 
				
			||||||
    test_divrem(div, -a, -b, r[3]);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* QuickJS BigInt extensions */
 | 
					 | 
				
			||||||
function test_bigint_ext()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    var r;
 | 
					 | 
				
			||||||
    assert(BigInt.floorLog2(0n) === -1n);
 | 
					 | 
				
			||||||
    assert(BigInt.floorLog2(7n) === 2n);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert(BigInt.sqrt(0xffffffc000000000000000n) === 17592185913343n);
 | 
					 | 
				
			||||||
    r = BigInt.sqrtrem(0xffffffc000000000000000n);
 | 
					 | 
				
			||||||
    assert(r[0] === 17592185913343n);
 | 
					 | 
				
			||||||
    assert(r[1] === 35167191957503n);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    test_idiv1("tdiv", 3n, 2n, [1n, -1n, -1n, 1n]);
 | 
					 | 
				
			||||||
    test_idiv1("fdiv", 3n, 2n, [1n, -2n, -2n, 1n]);
 | 
					 | 
				
			||||||
    test_idiv1("cdiv", 3n, 2n, [2n, -1n, -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");
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function test_bigdecimal()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    assert(1m === 1m);
 | 
					 | 
				
			||||||
    assert(1m !== 2m);
 | 
					 | 
				
			||||||
    test_less(1m, 2m);
 | 
					 | 
				
			||||||
    test_eq(2m, 2m);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    test_less(1, 2m);
 | 
					 | 
				
			||||||
    test_eq(2, 2m);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    test_less(1.1, 2m);
 | 
					 | 
				
			||||||
    test_eq(Math.sqrt(4), 2m);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    test_less(2n, 3m);
 | 
					 | 
				
			||||||
    test_eq(3n, 3m);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert(BigDecimal("1234.1") === 1234.1m);
 | 
					 | 
				
			||||||
    assert(BigDecimal("    1234.1") === 1234.1m);
 | 
					 | 
				
			||||||
    assert(BigDecimal("    1234.1  ") === 1234.1m);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert(BigDecimal(0.1) === 0.1m);
 | 
					 | 
				
			||||||
    assert(BigDecimal(123) === 123m);
 | 
					 | 
				
			||||||
    assert(BigDecimal(true) === 1m);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert(123m + 1m === 124m);
 | 
					 | 
				
			||||||
    assert(123m - 1m === 122m);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert(3.2m * 3m === 9.6m);
 | 
					 | 
				
			||||||
    assert(10m / 2m === 5m);
 | 
					 | 
				
			||||||
    assertThrows(RangeError, () => { 10m / 3m } );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert(10m % 3m === 1m);
 | 
					 | 
				
			||||||
    assert(-10m % 3m === -1m);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert(1234.5m ** 3m === 1881365963.625m);
 | 
					 | 
				
			||||||
    assertThrows(RangeError, () => { 2m ** 3.1m } );
 | 
					 | 
				
			||||||
    assertThrows(RangeError, () => { 2m ** -3m } );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert(BigDecimal.sqrt(2m,
 | 
					 | 
				
			||||||
                       { roundingMode: "half-even",
 | 
					 | 
				
			||||||
                         maximumSignificantDigits: 4 }) === 1.414m);
 | 
					 | 
				
			||||||
    assert(BigDecimal.sqrt(101m,
 | 
					 | 
				
			||||||
                       { roundingMode: "half-even",
 | 
					 | 
				
			||||||
                         maximumFractionDigits: 3 }) === 10.050m);
 | 
					 | 
				
			||||||
    assert(BigDecimal.sqrt(0.002m,
 | 
					 | 
				
			||||||
                       { roundingMode: "half-even",
 | 
					 | 
				
			||||||
                         maximumFractionDigits: 3 }) === 0.045m);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert(BigDecimal.round(3.14159m,
 | 
					 | 
				
			||||||
                       { roundingMode: "half-even",
 | 
					 | 
				
			||||||
                         maximumFractionDigits: 3 }) === 3.142m);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert(BigDecimal.add(3.14159m, 0.31212m,
 | 
					 | 
				
			||||||
                          { roundingMode: "half-even",
 | 
					 | 
				
			||||||
                            maximumFractionDigits: 2 }) === 3.45m);
 | 
					 | 
				
			||||||
    assert(BigDecimal.sub(3.14159m, 0.31212m,
 | 
					 | 
				
			||||||
                          { roundingMode: "down",
 | 
					 | 
				
			||||||
                            maximumFractionDigits: 2 }) === 2.82m);
 | 
					 | 
				
			||||||
    assert(BigDecimal.mul(3.14159m, 0.31212m,
 | 
					 | 
				
			||||||
                          { roundingMode: "half-even",
 | 
					 | 
				
			||||||
                            maximumFractionDigits: 3 }) === 0.981m);
 | 
					 | 
				
			||||||
    assert(BigDecimal.mod(3.14159m, 0.31211m,
 | 
					 | 
				
			||||||
                          { roundingMode: "half-even",
 | 
					 | 
				
			||||||
                            maximumFractionDigits: 4 }) === 0.0205m);
 | 
					 | 
				
			||||||
    assert(BigDecimal.div(20m, 3m,
 | 
					 | 
				
			||||||
                       { roundingMode: "half-even",
 | 
					 | 
				
			||||||
                         maximumSignificantDigits: 3 }) === 6.67m);
 | 
					 | 
				
			||||||
    assert(BigDecimal.div(20m, 3m,
 | 
					 | 
				
			||||||
                       { roundingMode: "half-even",
 | 
					 | 
				
			||||||
                         maximumFractionDigits: 50 }) ===
 | 
					 | 
				
			||||||
           6.66666666666666666666666666666666666666666666666667m);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* string conversion */
 | 
					 | 
				
			||||||
    assert((1234.125m).toString(), "1234.125");
 | 
					 | 
				
			||||||
    assert((1234.125m).toFixed(2), "1234.13");
 | 
					 | 
				
			||||||
    assert((1234.125m).toFixed(2, "down"), "1234.12");
 | 
					 | 
				
			||||||
    assert((1234.125m).toExponential(), "1.234125e+3");
 | 
					 | 
				
			||||||
    assert((1234.125m).toExponential(5), "1.23413e+3");
 | 
					 | 
				
			||||||
    assert((1234.125m).toExponential(5, "down"), "1.23412e+3");
 | 
					 | 
				
			||||||
    assert((1234.125m).toPrecision(6), "1234.13");
 | 
					 | 
				
			||||||
    assert((1234.125m).toPrecision(6, "down"), "1234.12");
 | 
					 | 
				
			||||||
    assert((-1234.125m).toPrecision(6, "floor"), "-1234.13");
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test_bigint_ext();
 | 
					 | 
				
			||||||
test_bigfloat();
 | 
					 | 
				
			||||||
test_bigdecimal();
 | 
					 | 
				
			||||||
							
								
								
									
										249
									
								
								tests/test_bigint.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										249
									
								
								tests/test_bigint.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,249 @@
 | 
				
			|||||||
 | 
					"use strict";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function assert(actual, expected, message) {
 | 
				
			||||||
 | 
					    if (arguments.length == 1)
 | 
				
			||||||
 | 
					        expected = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (actual === expected)
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (actual !== null && expected !== null
 | 
				
			||||||
 | 
					    &&  typeof actual == 'object' && typeof expected == 'object'
 | 
				
			||||||
 | 
					    &&  actual.toString() === expected.toString())
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    throw Error("assertion failed: got |" + actual + "|" +
 | 
				
			||||||
 | 
					                ", expected |" + expected + "|" +
 | 
				
			||||||
 | 
					                (message ? " (" + message + ")" : ""));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function assertThrows(err, func)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    var ex;
 | 
				
			||||||
 | 
					    ex = false;
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					        func();
 | 
				
			||||||
 | 
					    } catch(e) {
 | 
				
			||||||
 | 
					        ex = true;
 | 
				
			||||||
 | 
					        assert(e instanceof err);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    assert(ex, true, "exception expected");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// load more elaborate version of assert if available
 | 
				
			||||||
 | 
					try { __loadScript("test_assert.js"); } catch(e) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*----------------*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function bigint_pow(a, n)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    var r, i;
 | 
				
			||||||
 | 
					    r = 1n;
 | 
				
			||||||
 | 
					    for(i = 0n; i < n; i++)
 | 
				
			||||||
 | 
					        r *= a;
 | 
				
			||||||
 | 
					    return r;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* a must be < b */
 | 
				
			||||||
 | 
					function test_less(a, b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    assert(a < b);
 | 
				
			||||||
 | 
					    assert(!(b < a));
 | 
				
			||||||
 | 
					    assert(a <= b);
 | 
				
			||||||
 | 
					    assert(!(b <= a));
 | 
				
			||||||
 | 
					    assert(b > a);
 | 
				
			||||||
 | 
					    assert(!(a > b));
 | 
				
			||||||
 | 
					    assert(b >= a);
 | 
				
			||||||
 | 
					    assert(!(a >= b));
 | 
				
			||||||
 | 
					    assert(a != b);
 | 
				
			||||||
 | 
					    assert(!(a == b));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* a must be numerically equal to b */
 | 
				
			||||||
 | 
					function test_eq(a, b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    assert(a == b);
 | 
				
			||||||
 | 
					    assert(b == a);
 | 
				
			||||||
 | 
					    assert(!(a != b));
 | 
				
			||||||
 | 
					    assert(!(b != a));
 | 
				
			||||||
 | 
					    assert(a <= b);
 | 
				
			||||||
 | 
					    assert(b <= a);
 | 
				
			||||||
 | 
					    assert(!(a < b));
 | 
				
			||||||
 | 
					    assert(a >= b);
 | 
				
			||||||
 | 
					    assert(b >= a);
 | 
				
			||||||
 | 
					    assert(!(a > b));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function test_bigint1()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    var a, r;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    test_less(2n, 3n);
 | 
				
			||||||
 | 
					    test_eq(3n, 3n);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    test_less(2, 3n);
 | 
				
			||||||
 | 
					    test_eq(3, 3n);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    test_less(2.1, 3n);
 | 
				
			||||||
 | 
					    test_eq(Math.sqrt(4), 2n);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    a = bigint_pow(3n, 100n);
 | 
				
			||||||
 | 
					    assert((a - 1n) != a);
 | 
				
			||||||
 | 
					    assert(a == 515377520732011331036461129765621272702107522001n);
 | 
				
			||||||
 | 
					    assert(a == 0x5a4653ca673768565b41f775d6947d55cf3813d1n);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    r = 1n << 31n;
 | 
				
			||||||
 | 
					    assert(r, 2147483648n, "1 << 31n === 2147483648n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    r = 1n << 32n;
 | 
				
			||||||
 | 
					    assert(r, 4294967296n, "1 << 32n === 4294967296n");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function test_bigint2()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    assert(BigInt(""), 0n);
 | 
				
			||||||
 | 
					    assert(BigInt("  123"), 123n);
 | 
				
			||||||
 | 
					    assert(BigInt("  123   "), 123n);
 | 
				
			||||||
 | 
					    assertThrows(SyntaxError, () => { BigInt("+") } );
 | 
				
			||||||
 | 
					    assertThrows(SyntaxError, () => { BigInt("-") } );
 | 
				
			||||||
 | 
					    assertThrows(SyntaxError, () => { BigInt("\x00a") } );
 | 
				
			||||||
 | 
					    assertThrows(SyntaxError, () => { BigInt("  123  r") } );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function test_bigint3()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    assert(Number(0xffffffffffffffffn), 18446744073709552000);
 | 
				
			||||||
 | 
					    assert(Number(-0xffffffffffffffffn), -18446744073709552000);
 | 
				
			||||||
 | 
					    assert(100000000000000000000n == 1e20, true);
 | 
				
			||||||
 | 
					    assert(100000000000000000001n == 1e20, false);
 | 
				
			||||||
 | 
					    assert((1n << 100n).toString(10), "1267650600228229401496703205376");
 | 
				
			||||||
 | 
					    assert((-1n << 100n).toString(36), "-3ewfdnca0n6ld1ggvfgg");
 | 
				
			||||||
 | 
					    assert((1n << 100n).toString(8), "2000000000000000000000000000000000");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert(0x5a4653ca673768565b41f775n << 78n, 8443945299673273647701379149826607537748959488376832n);
 | 
				
			||||||
 | 
					    assert(-0x5a4653ca673768565b41f775n << 78n, -8443945299673273647701379149826607537748959488376832n);
 | 
				
			||||||
 | 
					    assert(0x5a4653ca673768565b41f775n >> 78n, 92441n);
 | 
				
			||||||
 | 
					    assert(-0x5a4653ca673768565b41f775n >> 78n, -92442n);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert(~0x5a653ca6n, -1516584103n);
 | 
				
			||||||
 | 
					    assert(0x5a463ca6n | 0x67376856n, 2138537206n);
 | 
				
			||||||
 | 
					    assert(0x5a463ca6n & 0x67376856n, 1107699718n);
 | 
				
			||||||
 | 
					    assert(0x5a463ca6n ^ 0x67376856n, 1030837488n);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert(3213213213213213432453243n / 123434343439n, 26031760073331n);
 | 
				
			||||||
 | 
					    assert(-3213213213213213432453243n / 123434343439n, -26031760073331n);
 | 
				
			||||||
 | 
					    assert(-3213213213213213432453243n % -123434343439n, -26953727934n);
 | 
				
			||||||
 | 
					    assert(3213213213213213432453243n % 123434343439n, 26953727934n);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert((-2n) ** 127n, -170141183460469231731687303715884105728n);
 | 
				
			||||||
 | 
					    assert((2n) ** 127n, 170141183460469231731687303715884105728n);
 | 
				
			||||||
 | 
					    assert((-256n) ** 11n, -309485009821345068724781056n);
 | 
				
			||||||
 | 
					    assert((7n) ** 20n, 79792266297612001n);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* pi computation */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* return floor(log2(a)) for a > 0 and 0 for a = 0 */
 | 
				
			||||||
 | 
					function floor_log2(a)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    var k_max, a1, k, i;
 | 
				
			||||||
 | 
					    k_max = 0n;
 | 
				
			||||||
 | 
					    while ((a >> (2n ** k_max)) != 0n) {
 | 
				
			||||||
 | 
					        k_max++;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    k = 0n;
 | 
				
			||||||
 | 
					    a1 = a;
 | 
				
			||||||
 | 
					    for(i = k_max - 1n; i >= 0n; i--) {
 | 
				
			||||||
 | 
					        a1 = a >> (2n ** i);
 | 
				
			||||||
 | 
					        if (a1 != 0n) {
 | 
				
			||||||
 | 
					            a = a1;
 | 
				
			||||||
 | 
					            k |= (1n << i);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return k;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* return ceil(log2(a)) for a > 0 */
 | 
				
			||||||
 | 
					function ceil_log2(a)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return floor_log2(a - 1n) + 1n;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* return floor(sqrt(a)) (not efficient but simple) */
 | 
				
			||||||
 | 
					function int_sqrt(a)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    var l, u, s;
 | 
				
			||||||
 | 
					    if (a == 0n)
 | 
				
			||||||
 | 
					        return a;
 | 
				
			||||||
 | 
					    l = ceil_log2(a);
 | 
				
			||||||
 | 
					    u = 1n << ((l + 1n) / 2n);
 | 
				
			||||||
 | 
					    /* u >= floor(sqrt(a)) */
 | 
				
			||||||
 | 
					    for(;;) {
 | 
				
			||||||
 | 
					        s = u;
 | 
				
			||||||
 | 
					        u = ((a / s) + s) / 2n;
 | 
				
			||||||
 | 
					        if (u >= s)
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return s;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* return pi * 2**prec */
 | 
				
			||||||
 | 
					function calc_pi(prec) {
 | 
				
			||||||
 | 
					    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 = G * (CHUD_B * b + CHUD_A);
 | 
				
			||||||
 | 
					            if (b & 1n)
 | 
				
			||||||
 | 
					                P = -P;
 | 
				
			||||||
 | 
					            Q = 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 = 0n;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return [P, Q, G];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    var n, P, Q, G;
 | 
				
			||||||
 | 
					    /* number of serie terms */
 | 
				
			||||||
 | 
					    n = BigInt(Math.ceil(Number(prec) / CHUD_BITS_PER_TERM)) + 10n;
 | 
				
			||||||
 | 
					    [P, Q, G] = chud_bs(0n, n, false);
 | 
				
			||||||
 | 
					    Q = (CHUD_C / 12n) * (Q << prec) / (P + Q * CHUD_A);
 | 
				
			||||||
 | 
					    G = int_sqrt(CHUD_C << (2n * prec));
 | 
				
			||||||
 | 
					    return (Q * G) >> prec;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function compute_pi(n_digits) {
 | 
				
			||||||
 | 
					    var r, n_digits, n_bits, out;
 | 
				
			||||||
 | 
					    /* we add more bits to reduce the probability of bad rounding for
 | 
				
			||||||
 | 
					      the last digits */
 | 
				
			||||||
 | 
					    n_bits = BigInt(Math.ceil(n_digits * Math.log2(10))) + 32n;
 | 
				
			||||||
 | 
					    r = calc_pi(n_bits);
 | 
				
			||||||
 | 
					    r = ((10n ** BigInt(n_digits)) * r) >> n_bits;
 | 
				
			||||||
 | 
					    out = r.toString();
 | 
				
			||||||
 | 
					    return out[0] + "." + out.slice(1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function test_pi()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    assert(compute_pi(2000), "3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316527120190914564856692346034861045432664821339360726024914127372458700660631558817488152092096282925409171536436789259036001133053054882046652138414695194151160943305727036575959195309218611738193261179310511854807446237996274956735188575272489122793818301194912983367336244065664308602139494639522473719070217986094370277053921717629317675238467481846766940513200056812714526356082778577134275778960917363717872146844090122495343014654958537105079227968925892354201995611212902196086403441815981362977477130996051870721134999999837297804995105973173281609631859502445945534690830264252230825334468503526193118817101000313783875288658753320838142061717766914730359825349042875546873115956286388235378759375195778185778053217122680661300192787661119590921642019893809525720106548586327886593615338182796823030195203530185296899577362259941389124972177528347913151557485724245415069595082953311686172785588907509838175463746493931925506040092770167113900984882401285836160356370766010471018194295559619894676783744944825537977472684710404753464620804668425906949129331367702898915210475216205696602405803815019351125338243003558764024749647326391419927260426992279678235478163600934172164121992458631503028618297455570674983850549458858692699569092721079750930295532116534498720275596023648066549911988183479775356636980742654252786255181841757467289097777279380008164706001614524919217321721477235014144197356854816136115735255213347574184946843852332390739414333454776241686251898356948556209921922218427255025425688767179049460165346680498862723279178608578438382796797668145410095388378636095068006422512520511739298489608412848862694560424196528502221066118630674427862203919494504712371378696095636437191728746776465757396241389086583264599581339047802759009");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_bigint1();
 | 
				
			||||||
 | 
					test_bigint2();
 | 
				
			||||||
 | 
					test_bigint3();
 | 
				
			||||||
 | 
					test_pi();
 | 
				
			||||||
@ -1,114 +0,0 @@
 | 
				
			|||||||
"use strict";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function assert(actual, expected, message) {
 | 
					 | 
				
			||||||
    if (arguments.length == 1)
 | 
					 | 
				
			||||||
        expected = true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (actual === expected)
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (actual !== null && expected !== null
 | 
					 | 
				
			||||||
    &&  typeof actual == 'object' && typeof expected == 'object'
 | 
					 | 
				
			||||||
    &&  actual.toString() === expected.toString())
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    throw Error("assertion failed: got |" + actual + "|" +
 | 
					 | 
				
			||||||
                ", expected |" + expected + "|" +
 | 
					 | 
				
			||||||
                (message ? " (" + message + ")" : ""));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function assertThrows(err, func)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    var ex;
 | 
					 | 
				
			||||||
    ex = false;
 | 
					 | 
				
			||||||
    try {
 | 
					 | 
				
			||||||
        func();
 | 
					 | 
				
			||||||
    } catch(e) {
 | 
					 | 
				
			||||||
        ex = true;
 | 
					 | 
				
			||||||
        assert(e instanceof err);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    assert(ex, true, "exception expected");
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// load more elaborate version of assert if available
 | 
					 | 
				
			||||||
try { __loadScript("test_assert.js"); } catch(e) {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*----------------*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function bigint_pow(a, n)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    var r, i;
 | 
					 | 
				
			||||||
    r = 1n;
 | 
					 | 
				
			||||||
    for(i = 0n; i < n; i++)
 | 
					 | 
				
			||||||
        r *= a;
 | 
					 | 
				
			||||||
    return r;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* a must be < b */
 | 
					 | 
				
			||||||
function test_less(a, b)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    assert(a < b);
 | 
					 | 
				
			||||||
    assert(!(b < a));
 | 
					 | 
				
			||||||
    assert(a <= b);
 | 
					 | 
				
			||||||
    assert(!(b <= a));
 | 
					 | 
				
			||||||
    assert(b > a);
 | 
					 | 
				
			||||||
    assert(!(a > b));
 | 
					 | 
				
			||||||
    assert(b >= a);
 | 
					 | 
				
			||||||
    assert(!(a >= b));
 | 
					 | 
				
			||||||
    assert(a != b);
 | 
					 | 
				
			||||||
    assert(!(a == b));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* a must be numerically equal to b */
 | 
					 | 
				
			||||||
function test_eq(a, b)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    assert(a == b);
 | 
					 | 
				
			||||||
    assert(b == a);
 | 
					 | 
				
			||||||
    assert(!(a != b));
 | 
					 | 
				
			||||||
    assert(!(b != a));
 | 
					 | 
				
			||||||
    assert(a <= b);
 | 
					 | 
				
			||||||
    assert(b <= a);
 | 
					 | 
				
			||||||
    assert(!(a < b));
 | 
					 | 
				
			||||||
    assert(a >= b);
 | 
					 | 
				
			||||||
    assert(b >= a);
 | 
					 | 
				
			||||||
    assert(!(a > b));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function test_bigint1()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    var a, r;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    test_less(2n, 3n);
 | 
					 | 
				
			||||||
    test_eq(3n, 3n);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    test_less(2, 3n);
 | 
					 | 
				
			||||||
    test_eq(3, 3n);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    test_less(2.1, 3n);
 | 
					 | 
				
			||||||
    test_eq(Math.sqrt(4), 2n);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    a = bigint_pow(3n, 100n);
 | 
					 | 
				
			||||||
    assert((a - 1n) != a);
 | 
					 | 
				
			||||||
    assert(a == 515377520732011331036461129765621272702107522001n);
 | 
					 | 
				
			||||||
    assert(a == 0x5a4653ca673768565b41f775d6947d55cf3813d1n);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    r = 1n << 31n;
 | 
					 | 
				
			||||||
    assert(r, 2147483648n, "1 << 31n === 2147483648n");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    r = 1n << 32n;
 | 
					 | 
				
			||||||
    assert(r, 4294967296n, "1 << 32n === 4294967296n");
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function test_bigint2()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    assert(BigInt(""), 0n);
 | 
					 | 
				
			||||||
    assert(BigInt("  123"), 123n);
 | 
					 | 
				
			||||||
    assert(BigInt("  123   "), 123n);
 | 
					 | 
				
			||||||
    assertThrows(SyntaxError, () => { BigInt("+") } );
 | 
					 | 
				
			||||||
    assertThrows(SyntaxError, () => { BigInt("-") } );
 | 
					 | 
				
			||||||
    assertThrows(SyntaxError, () => { BigInt("\x00a") } );
 | 
					 | 
				
			||||||
    assertThrows(SyntaxError, () => { BigInt("  123  r") } );
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test_bigint1();
 | 
					 | 
				
			||||||
test_bigint2();
 | 
					 | 
				
			||||||
@ -1,207 +0,0 @@
 | 
				
			|||||||
"use strict";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function assert(actual, expected, message) {
 | 
					 | 
				
			||||||
    if (arguments.length == 1)
 | 
					 | 
				
			||||||
        expected = true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (actual === expected)
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (actual !== null && expected !== null
 | 
					 | 
				
			||||||
    &&  typeof actual == 'object' && typeof expected == 'object'
 | 
					 | 
				
			||||||
    &&  actual.toString() === expected.toString())
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    throw Error("assertion failed: got |" + actual + "|" +
 | 
					 | 
				
			||||||
                ", expected |" + expected + "|" +
 | 
					 | 
				
			||||||
                (message ? " (" + message + ")" : ""));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* operators overloading with Operators.create() */
 | 
					 | 
				
			||||||
function test_operators_create() {
 | 
					 | 
				
			||||||
    class Vec2
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        constructor(x, y) {
 | 
					 | 
				
			||||||
            this.x = x;
 | 
					 | 
				
			||||||
            this.y = y;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        static mul_scalar(p1, a) {
 | 
					 | 
				
			||||||
            var r = new Vec2();
 | 
					 | 
				
			||||||
            r.x = p1.x * a;
 | 
					 | 
				
			||||||
            r.y = p1.y * a;
 | 
					 | 
				
			||||||
            return r;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        toString() {
 | 
					 | 
				
			||||||
            return "Vec2(" + this.x + "," + this.y + ")";
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Vec2.prototype[Symbol.operatorSet] = Operators.create(
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        "+"(p1, p2) {
 | 
					 | 
				
			||||||
            var r = new Vec2();
 | 
					 | 
				
			||||||
            r.x = p1.x + p2.x;
 | 
					 | 
				
			||||||
            r.y = p1.y + p2.y;
 | 
					 | 
				
			||||||
            return r;
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        "-"(p1, p2) {
 | 
					 | 
				
			||||||
            var r = new Vec2();
 | 
					 | 
				
			||||||
            r.x = p1.x - p2.x;
 | 
					 | 
				
			||||||
            r.y = p1.y - p2.y;
 | 
					 | 
				
			||||||
            return r;
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        "=="(a, b) {
 | 
					 | 
				
			||||||
            return a.x == b.x && a.y == b.y;
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        "<"(a, b) {
 | 
					 | 
				
			||||||
            var r;
 | 
					 | 
				
			||||||
            /* lexicographic order */
 | 
					 | 
				
			||||||
            if (a.x == b.x)
 | 
					 | 
				
			||||||
                r = (a.y < b.y);
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
                r = (a.x < b.x);
 | 
					 | 
				
			||||||
            return r;
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        "++"(a) {
 | 
					 | 
				
			||||||
            var r = new Vec2();
 | 
					 | 
				
			||||||
            r.x = a.x + 1;
 | 
					 | 
				
			||||||
            r.y = a.y + 1;
 | 
					 | 
				
			||||||
            return r;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        left: Number,
 | 
					 | 
				
			||||||
        "*"(a, b) {
 | 
					 | 
				
			||||||
            return Vec2.mul_scalar(b, a);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        right: Number,
 | 
					 | 
				
			||||||
        "*"(a, b) {
 | 
					 | 
				
			||||||
            return Vec2.mul_scalar(a, b);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    var a = new Vec2(1, 2);
 | 
					 | 
				
			||||||
    var b = new Vec2(3, 4);
 | 
					 | 
				
			||||||
    var r;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    r = a * 2 + 3 * b;
 | 
					 | 
				
			||||||
    assert(r.x === 11 && r.y === 16);
 | 
					 | 
				
			||||||
    assert(a == a, true);
 | 
					 | 
				
			||||||
    assert(a == b, false);
 | 
					 | 
				
			||||||
    assert(a != a, false);
 | 
					 | 
				
			||||||
    assert(a < b, true);
 | 
					 | 
				
			||||||
    assert(a <= b, true);
 | 
					 | 
				
			||||||
    assert(b < a, false);
 | 
					 | 
				
			||||||
    assert(b <= a, false);
 | 
					 | 
				
			||||||
    assert(a <= a, true);
 | 
					 | 
				
			||||||
    assert(a >= a, true);
 | 
					 | 
				
			||||||
    a++;
 | 
					 | 
				
			||||||
    assert(a.x === 2 && a.y === 3);
 | 
					 | 
				
			||||||
    r = ++a;
 | 
					 | 
				
			||||||
    assert(a.x === 3 && a.y === 4);
 | 
					 | 
				
			||||||
    assert(r === a);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* operators overloading thru inheritance */
 | 
					 | 
				
			||||||
function test_operators()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    var Vec2;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    function mul_scalar(p1, a) {
 | 
					 | 
				
			||||||
        var r = new Vec2();
 | 
					 | 
				
			||||||
        r.x = p1.x * a;
 | 
					 | 
				
			||||||
        r.y = p1.y * a;
 | 
					 | 
				
			||||||
        return r;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    var vec2_ops = Operators({
 | 
					 | 
				
			||||||
        "+"(p1, p2) {
 | 
					 | 
				
			||||||
            var r = new Vec2();
 | 
					 | 
				
			||||||
            r.x = p1.x + p2.x;
 | 
					 | 
				
			||||||
            r.y = p1.y + p2.y;
 | 
					 | 
				
			||||||
            return r;
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        "-"(p1, p2) {
 | 
					 | 
				
			||||||
            var r = new Vec2();
 | 
					 | 
				
			||||||
            r.x = p1.x - p2.x;
 | 
					 | 
				
			||||||
            r.y = p1.y - p2.y;
 | 
					 | 
				
			||||||
            return r;
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        "=="(a, b) {
 | 
					 | 
				
			||||||
            return a.x == b.x && a.y == b.y;
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        "<"(a, b) {
 | 
					 | 
				
			||||||
            var r;
 | 
					 | 
				
			||||||
            /* lexicographic order */
 | 
					 | 
				
			||||||
            if (a.x == b.x)
 | 
					 | 
				
			||||||
                r = (a.y < b.y);
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
                r = (a.x < b.x);
 | 
					 | 
				
			||||||
            return r;
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        "++"(a) {
 | 
					 | 
				
			||||||
            var r = new Vec2();
 | 
					 | 
				
			||||||
            r.x = a.x + 1;
 | 
					 | 
				
			||||||
            r.y = a.y + 1;
 | 
					 | 
				
			||||||
            return r;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        left: Number,
 | 
					 | 
				
			||||||
        "*"(a, b) {
 | 
					 | 
				
			||||||
            return mul_scalar(b, a);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        right: Number,
 | 
					 | 
				
			||||||
        "*"(a, b) {
 | 
					 | 
				
			||||||
            return mul_scalar(a, b);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Vec2 = class Vec2 extends vec2_ops
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        constructor(x, y) {
 | 
					 | 
				
			||||||
            super();
 | 
					 | 
				
			||||||
            this.x = x;
 | 
					 | 
				
			||||||
            this.y = y;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        toString() {
 | 
					 | 
				
			||||||
            return "Vec2(" + this.x + "," + this.y + ")";
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    var a = new Vec2(1, 2);
 | 
					 | 
				
			||||||
    var b = new Vec2(3, 4);
 | 
					 | 
				
			||||||
    var r;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    r = a * 2 + 3 * b;
 | 
					 | 
				
			||||||
    assert(r.x === 11 && r.y === 16);
 | 
					 | 
				
			||||||
    assert(a == a, true);
 | 
					 | 
				
			||||||
    assert(a == b, false);
 | 
					 | 
				
			||||||
    assert(a != a, false);
 | 
					 | 
				
			||||||
    assert(a < b, true);
 | 
					 | 
				
			||||||
    assert(a <= b, true);
 | 
					 | 
				
			||||||
    assert(b < a, false);
 | 
					 | 
				
			||||||
    assert(b <= a, false);
 | 
					 | 
				
			||||||
    assert(a <= a, true);
 | 
					 | 
				
			||||||
    assert(a >= a, true);
 | 
					 | 
				
			||||||
    a++;
 | 
					 | 
				
			||||||
    assert(a.x === 2 && a.y === 3);
 | 
					 | 
				
			||||||
    r = ++a;
 | 
					 | 
				
			||||||
    assert(a.x === 3 && a.y === 4);
 | 
					 | 
				
			||||||
    assert(r === a);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function test_default_op()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    assert(Object(1) + 2, 3);
 | 
					 | 
				
			||||||
    assert(Object(1) + true, 2);
 | 
					 | 
				
			||||||
    assert(-Object(1), -1);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test_operators_create();
 | 
					 | 
				
			||||||
test_operators();
 | 
					 | 
				
			||||||
test_default_op();
 | 
					 | 
				
			||||||
@ -1,256 +0,0 @@
 | 
				
			|||||||
"use math";
 | 
					 | 
				
			||||||
"use strict";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function assert(actual, expected, message) {
 | 
					 | 
				
			||||||
    if (arguments.length == 1)
 | 
					 | 
				
			||||||
        expected = true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (actual === expected)
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (actual !== null && expected !== null
 | 
					 | 
				
			||||||
    &&  typeof actual == 'object' && typeof expected == 'object'
 | 
					 | 
				
			||||||
    &&  actual.toString() === expected.toString())
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    throw Error("assertion failed: got |" + actual + "|" +
 | 
					 | 
				
			||||||
                ", expected |" + expected + "|" +
 | 
					 | 
				
			||||||
                (message ? " (" + message + ")" : ""));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function assertThrows(err, func)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    var ex;
 | 
					 | 
				
			||||||
    ex = false;
 | 
					 | 
				
			||||||
    try {
 | 
					 | 
				
			||||||
        func();
 | 
					 | 
				
			||||||
    } catch(e) {
 | 
					 | 
				
			||||||
        ex = true;
 | 
					 | 
				
			||||||
        assert(e instanceof err);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    assert(ex, true, "exception expected");
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// load more elaborate version of assert if available
 | 
					 | 
				
			||||||
try { __loadScript("test_assert.js"); } catch(e) {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*----------------*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function pow(a, n)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    var r, i;
 | 
					 | 
				
			||||||
    r = 1;
 | 
					 | 
				
			||||||
    for(i = 0; i < n; i++)
 | 
					 | 
				
			||||||
        r *= a;
 | 
					 | 
				
			||||||
    return r;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function test_integer()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    var a, r;
 | 
					 | 
				
			||||||
    a = pow(3, 100);
 | 
					 | 
				
			||||||
    assert((a - 1) != a);
 | 
					 | 
				
			||||||
    assert(a == 515377520732011331036461129765621272702107522001);
 | 
					 | 
				
			||||||
    assert(a == 0x5a4653ca673768565b41f775d6947d55cf3813d1);
 | 
					 | 
				
			||||||
    assert(Integer.isInteger(1) === true);
 | 
					 | 
				
			||||||
    assert(Integer.isInteger(1.0) === false);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert(Integer.floorLog2(0) === -1);
 | 
					 | 
				
			||||||
    assert(Integer.floorLog2(7) === 2);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    r = 1 << 31;
 | 
					 | 
				
			||||||
    assert(r, 2147483648, "1 << 31 === 2147483648");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    r = 1 << 32;
 | 
					 | 
				
			||||||
    assert(r, 4294967296, "1 << 32 === 4294967296");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    r = (1 << 31) < 0;
 | 
					 | 
				
			||||||
    assert(r, false, "(1 << 31) < 0 === false");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert(typeof 1 === "number");
 | 
					 | 
				
			||||||
    assert(typeof 9007199254740991 === "number");
 | 
					 | 
				
			||||||
    assert(typeof 9007199254740992 === "bigint");
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function test_float()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    assert(typeof 1.0 === "bigfloat");
 | 
					 | 
				
			||||||
    assert(1 == 1.0);
 | 
					 | 
				
			||||||
    assert(1 !== 1.0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* jscalc tests */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function test_modulo()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    var i, p, a, b;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* Euclidian modulo operator */
 | 
					 | 
				
			||||||
    assert((-3) % 2 == 1);
 | 
					 | 
				
			||||||
    assert(3 % (-2) == 1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    p = 101;
 | 
					 | 
				
			||||||
    for(i = 1; i < p; i++) {
 | 
					 | 
				
			||||||
        a = Integer.invmod(i, p);
 | 
					 | 
				
			||||||
        assert(a >= 0 && a < p);
 | 
					 | 
				
			||||||
        assert((i * a) % p == 1);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert(Integer.isPrime(2^107-1));
 | 
					 | 
				
			||||||
    assert(!Integer.isPrime((2^107-1) * (2^89-1)));
 | 
					 | 
				
			||||||
    a = Integer.factor((2^89-1)*2^3*11*13^2*1009);
 | 
					 | 
				
			||||||
    assert(a == [ 2,2,2,11,13,13,1009,618970019642690137449562111 ]);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function test_fraction()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    assert((1/3 + 1).toString(), "4/3")
 | 
					 | 
				
			||||||
    assert((2/3)^30, 1073741824/205891132094649);
 | 
					 | 
				
			||||||
    assert(1/3 < 2/3);
 | 
					 | 
				
			||||||
    assert(1/3 < 1);
 | 
					 | 
				
			||||||
    assert(1/3 == 1.0/3);
 | 
					 | 
				
			||||||
    assert(1.0/3 < 2/3);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function test_mod()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    var a, b, p;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    a = Mod(3, 101);
 | 
					 | 
				
			||||||
    b = Mod(-1, 101);
 | 
					 | 
				
			||||||
    assert((a + b) == Mod(2, 101));
 | 
					 | 
				
			||||||
    assert(a ^ 100 == Mod(1, 101));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    p = 2 ^ 607 - 1; /* mersenne prime */
 | 
					 | 
				
			||||||
    a = Mod(3, p) ^ (p - 1);
 | 
					 | 
				
			||||||
    assert(a == Mod(1, p));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function test_polynomial()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    var a, b, q, r, t, i;
 | 
					 | 
				
			||||||
    a = (1 + X) ^ 4;
 | 
					 | 
				
			||||||
    assert(a == X^4+4*X^3+6*X^2+4*X+1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    r = (1 + X);
 | 
					 | 
				
			||||||
    q = (1+X+X^2);
 | 
					 | 
				
			||||||
    b = (1 - X^2);
 | 
					 | 
				
			||||||
    a = q * b + r;
 | 
					 | 
				
			||||||
    t = Polynomial.divrem(a, b);
 | 
					 | 
				
			||||||
    assert(t[0] == q);
 | 
					 | 
				
			||||||
    assert(t[1] == r);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    a = 1 + 2*X + 3*X^2;
 | 
					 | 
				
			||||||
    assert(a.apply(0.1) == 1.23);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    a = 1-2*X^2+2*X^3;
 | 
					 | 
				
			||||||
    assert(deriv(a) == (6*X^2-4*X));
 | 
					 | 
				
			||||||
    assert(deriv(integ(a)) == a);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    a = (X-1)*(X-2)*(X-3)*(X-4)*(X-0.1);
 | 
					 | 
				
			||||||
    r = polroots(a);
 | 
					 | 
				
			||||||
    for(i = 0; i < r.length; i++) {
 | 
					 | 
				
			||||||
        b = abs(a.apply(r[i]));
 | 
					 | 
				
			||||||
        assert(b <= 1e-13);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function test_poly_mod()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    var a, p;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* modulo using polynomials */
 | 
					 | 
				
			||||||
    p = X^2 + X + 1;
 | 
					 | 
				
			||||||
    a = PolyMod(3+X, p) ^ 10;
 | 
					 | 
				
			||||||
    assert(a == PolyMod(-3725*X-18357, p));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    a = PolyMod(1/X, 1+X^2);
 | 
					 | 
				
			||||||
    assert(a == PolyMod(-X, X^2+1));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function test_rfunc()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    var a;
 | 
					 | 
				
			||||||
    a = (X+1)/((X+1)*(X-1));
 | 
					 | 
				
			||||||
    assert(a == 1/(X-1));
 | 
					 | 
				
			||||||
    a = (X + 2) / (X - 2);
 | 
					 | 
				
			||||||
    assert(a.apply(1/3) == -7/5);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert(deriv((X^2-X+1)/(X-1)) == (X^2-2*X)/(X^2-2*X+1));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function test_series()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    var a, b;
 | 
					 | 
				
			||||||
    a = 1+X+O(X^5);
 | 
					 | 
				
			||||||
    b = a.inverse();
 | 
					 | 
				
			||||||
    assert(b == 1-X+X^2-X^3+X^4+O(X^5));
 | 
					 | 
				
			||||||
    assert(deriv(b) == -1+2*X-3*X^2+4*X^3+O(X^4));
 | 
					 | 
				
			||||||
    assert(deriv(integ(b)) == b);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    a = Series(1/(1-X), 5);
 | 
					 | 
				
			||||||
    assert(a == 1+X+X^2+X^3+X^4+O(X^5));
 | 
					 | 
				
			||||||
    b = a.apply(0.1);
 | 
					 | 
				
			||||||
    assert(b == 1.1111);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert(exp(3*X^2+O(X^10)) == 1+3*X^2+9/2*X^4+9/2*X^6+27/8*X^8+O(X^10));
 | 
					 | 
				
			||||||
    assert(sin(X+O(X^6)) == X-1/6*X^3+1/120*X^5+O(X^6));
 | 
					 | 
				
			||||||
    assert(cos(X+O(X^6)) == 1-1/2*X^2+1/24*X^4+O(X^6));
 | 
					 | 
				
			||||||
    assert(tan(X+O(X^8)) == X+1/3*X^3+2/15*X^5+17/315*X^7+O(X^8));
 | 
					 | 
				
			||||||
        assert((1+X+O(X^6))^(2+X) == 1+2*X+2*X^2+3/2*X^3+5/6*X^4+5/12*X^5+O(X^6));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function test_matrix()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    var a, b, r;
 | 
					 | 
				
			||||||
    a = [[1, 2],[3, 4]];
 | 
					 | 
				
			||||||
    b = [3, 4];
 | 
					 | 
				
			||||||
    r = a * b;
 | 
					 | 
				
			||||||
    assert(r == [11, 25]);
 | 
					 | 
				
			||||||
    r = (a^-1) * 2;
 | 
					 | 
				
			||||||
    assert(r == [[-4, 2],[3, -1]]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert(norm2([1,2,3]) == 14);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert(diag([1,2,3]) == [ [ 1, 0, 0 ], [ 0, 2, 0 ], [ 0, 0, 3 ] ]);
 | 
					 | 
				
			||||||
    assert(trans(a) == [ [ 1, 3 ], [ 2, 4 ] ]);
 | 
					 | 
				
			||||||
    assert(trans([1,2,3]) == [[1,2,3]]);
 | 
					 | 
				
			||||||
    assert(trace(a) == 5);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert(charpoly(Matrix.hilbert(4)) == X^4-176/105*X^3+3341/12600*X^2-41/23625*X+1/6048000);
 | 
					 | 
				
			||||||
    assert(det(Matrix.hilbert(4)) == 1/6048000);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    a = [[1,2,1],[-2,-3,1],[3,5,0]];
 | 
					 | 
				
			||||||
    assert(rank(a) == 2);
 | 
					 | 
				
			||||||
    assert(ker(a) == [ [ 5 ], [ -3 ], [ 1 ] ]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert(dp([1, 2, 3], [3, -4, -7]) === -26);
 | 
					 | 
				
			||||||
    assert(cp([1, 2, 3], [3, -4, -7]) == [ -2, 16, -10 ]);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function assert_eq(a, ref)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    assert(abs(a / ref - 1.0) <= 1e-15);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function test_trig()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    assert_eq(sin(1/2), 0.479425538604203);
 | 
					 | 
				
			||||||
    assert_eq(sin(2+3*I), 9.154499146911428-4.168906959966565*I);
 | 
					 | 
				
			||||||
    assert_eq(cos(2+3*I), -4.189625690968807-9.109227893755337*I);
 | 
					 | 
				
			||||||
    assert_eq((2+0.5*I)^(1.1-0.5*I), 2.494363021357619-0.23076804554558092*I);
 | 
					 | 
				
			||||||
    assert_eq(sqrt(2*I), 1 + I);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test_integer();
 | 
					 | 
				
			||||||
test_float();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test_modulo();
 | 
					 | 
				
			||||||
test_fraction();
 | 
					 | 
				
			||||||
test_mod();
 | 
					 | 
				
			||||||
test_polynomial();
 | 
					 | 
				
			||||||
test_poly_mod();
 | 
					 | 
				
			||||||
test_rfunc();
 | 
					 | 
				
			||||||
test_series();
 | 
					 | 
				
			||||||
test_matrix();
 | 
					 | 
				
			||||||
test_trig();
 | 
					 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user