Bignum-compatible version of ash

This commit is contained in:
Justin Ethier 2017-04-01 00:14:02 -04:00
parent c0a5daf898
commit afa12cec5f

View file

@ -203,50 +203,57 @@
(ash from start) (ash from start)
to)) to))
(define-c ash ;(define-c ash
"(void* data, int argc, closure _, object k, object x, object y)" ; "(void* data, int argc, closure _, object k, object x, object y)"
"Cyc_check_int(data, x); ; "Cyc_check_int(data, x);
Cyc_check_int(data,y); ; Cyc_check_int(data,y);
int bf = (int)unbox_number(x); ; int bf = (int)unbox_number(x);
int shift = (int)unbox_number(y); ; int shift = (int)unbox_number(y);
//int i; ; //int i;
if (shift > 0) { ; if (shift > 0) {
bf <<= shift; ; bf <<= shift;
} else { ; } else {
bf >>= abs(shift); ; bf >>= abs(shift);
} ; }
// if (shift > 0) { ;// if (shift > 0) {
// for (i = 0; i < shift; i++) { ;// for (i = 0; i < shift; i++) {
// bf *= 2; ;// bf *= 2;
// } ;// }
// } else { ;// } else {
// for (i = 0; i < abs(shift); i++) { ;// for (i = 0; i < abs(shift); i++) {
// bf /= 2; ;// bf /= 2;
// } ;// }
// } ;// }
return_closcall1(data, k, obj_int2obj(bf))") ; return_closcall1(data, k, obj_int2obj(bf))")
;; (define-c ash (define-c ash
;; "(void* data, int argc, closure _, object k, object x, object y)" "(void* data, int argc, closure _, object k, object x, object y)"
;; "Cyc_check_int(data, x); "Cyc_check_int(data, x);
;; Cyc_check_fixnum(data,y); Cyc_check_fixnum(data,y);
;; int shift; int shift, i;
;; //int result; //int result;
;; alloc_bignum(data, bn); alloc_bignum(data, bn);
;;
;; if (obj_is_int(x)) { if (Cyc_is_bignum(x) == boolean_t){
;; Cyc_int2bignum(obj_obj2int(x), &bignum_value(bn)); mp_copy(&bignum_value(x), &bignum_value(bn));
;; } else { } else {
;; mp_copy(&bignum_value(x), &bignum_value(bn)); Cyc_int2bignum((int)unbox_number(x), &bignum_value(bn));
;; } }
;;
;; shift = (int)unbox_number(y); // Inefficient but always works without overflow
;; if (shift > 0) { // Should be able to do pure fixnum math in some cases, though
;; mp_lshd(&bignum_value(bn), shift); shift = (int)unbox_number(y);
;; } else { if (shift > 0) {
;; mp_rshd(&bignum_value(bn), abs(shift)); for (i = 0; i < shift; i++) {
;; } mp_mul_2(&bignum_value(bn), &bignum_value(bn));
;; return_closcall1(data, k, Cyc_bignum_normalize(data, bn));") }
} else {
for (i = 0; i < abs(shift); i++) {
mp_div_2(&bignum_value(bn), &bignum_value(bn));
}
}
return_closcall1(data, k, Cyc_bignum_normalize(data, bn));")
(define arithmetic-shift ash) (define arithmetic-shift ash)