* Added floor/ceiling.
This commit is contained in:
parent
57f4d16ee2
commit
0480517615
BIN
bin/ikarus
BIN
bin/ikarus
Binary file not shown.
|
@ -1100,6 +1100,17 @@ add_object_proc(gc_t* gc, ikp x)
|
|||
ref(x, wordsize-vector_tag) = new;
|
||||
return new;
|
||||
}
|
||||
else if(fst == ratnum_tag){
|
||||
ikp y = gc_alloc_new_data(ratnum_size, gen, gc) + vector_tag;
|
||||
ikp num = ref(x, disp_ratnum_num-vector_tag);
|
||||
ikp den = ref(x, disp_ratnum_den-vector_tag);
|
||||
ref(x, -vector_tag) = forward_ptr;
|
||||
ref(x, wordsize-vector_tag) = y;
|
||||
ref(y, -vector_tag) = fst;
|
||||
ref(y, disp_ratnum_num-vector_tag) = add_object(gc, num, "num");
|
||||
ref(y, disp_ratnum_den-vector_tag) = add_object(gc, den, "den");
|
||||
return y;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "unhandled vector with fst=0x%08x\n", (int)fst);
|
||||
assert(0);
|
||||
|
@ -1109,12 +1120,12 @@ add_object_proc(gc_t* gc, ikp x)
|
|||
else if(tag == string_tag){
|
||||
if(is_fixnum(fst)){
|
||||
int strlen = unfix(fst);
|
||||
int memreq = align(strlen*string_char_size + disp_string_data + 1);
|
||||
int memreq = align(strlen*string_char_size + disp_string_data);
|
||||
ikp new_str = gc_alloc_new_data(memreq, gen, gc) + string_tag;
|
||||
ref(new_str, off_string_length) = fst;
|
||||
memcpy(new_str+off_string_data,
|
||||
x + off_string_data,
|
||||
strlen*string_char_size + 1);
|
||||
strlen*string_char_size);
|
||||
ref(x, -string_tag) = forward_ptr;
|
||||
ref(x, wordsize-string_tag) = new_str;
|
||||
#if accounting
|
||||
|
|
|
@ -234,4 +234,10 @@
|
|||
#define off_flonum_data (disp_flonum_data - vector_tag)
|
||||
#define flonum_data(x) (*((double*)(((ikp)(x))+off_flonum_data)))
|
||||
|
||||
#define ratnum_tag ((ikp) 0x27)
|
||||
#define ratnum_size 16
|
||||
#define disp_ratnum_num 4
|
||||
#define disp_ratnum_den 8
|
||||
#define disp_ratnum_unused 12
|
||||
|
||||
#endif
|
||||
|
|
|
@ -186,13 +186,17 @@ ikrt_bignum_to_flonum(ikp x, ikpcb* pcb){
|
|||
ref(r, -vector_tag) = (ikp)flonum_tag;
|
||||
unsigned int fst = (unsigned int) ref(x, -vector_tag);
|
||||
int limbs = (fst >> bignum_length_shift);
|
||||
fprintf(stderr, "limbs=%d\n", limbs);
|
||||
double fl;
|
||||
if(limbs == 1){
|
||||
fl = ((unsigned int)ref(x, disp_bignum_data - vector_tag));
|
||||
} else if(limbs == 2){
|
||||
fl = ((unsigned int)ref(x, wordsize+disp_bignum_data - vector_tag));
|
||||
fprintf(stderr, "fl=%f\t", fl);
|
||||
fl *= exp2(32);
|
||||
fprintf(stderr, "fl=%f\t", fl);
|
||||
fl += ((unsigned int)ref(x, disp_bignum_data - vector_tag));
|
||||
fprintf(stderr, "fl=%f\n", fl);
|
||||
} else {
|
||||
fl =
|
||||
((unsigned int)ref(x, limbs * wordsize - wordsize +
|
||||
|
@ -209,6 +213,14 @@ ikrt_bignum_to_flonum(ikp x, ikpcb* pcb){
|
|||
fl = -fl;
|
||||
}
|
||||
flonum_data(r) = fl;
|
||||
{
|
||||
int i;
|
||||
unsigned char* p = (unsigned char*)(r+disp_flonum_data-vector_tag);
|
||||
for(i=0; i<8; i++){
|
||||
fprintf(stderr, "%02x ", p[7-i]);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
|
@ -102,7 +102,10 @@ verify_code_page(unsigned char* p, unsigned int s, unsigned int d,
|
|||
unsigned char* base, unsigned int* svec, unsigned int* dvec){
|
||||
ikp fst = ref(p, 0);
|
||||
fst += 0;
|
||||
assert (fst == code_tag);
|
||||
if(fst != code_tag){
|
||||
fprintf(stderr, "non code object with tag %p found\n", fst);
|
||||
exit(-1);
|
||||
}
|
||||
int code_size = unfix(ref(p, disp_code_code_size));
|
||||
assert(code_size >= 0);
|
||||
int obj_size = align(code_size + disp_code_data);
|
||||
|
|
BIN
src/ikarus.boot
BIN
src/ikarus.boot
Binary file not shown.
|
@ -5,9 +5,10 @@
|
|||
|
||||
|
||||
(library (ikarus flonums)
|
||||
(export string->flonum flonum->string)
|
||||
(export string->flonum flonum->string $flonum->exact)
|
||||
(import
|
||||
(ikarus system $bytevectors)
|
||||
(ikarus system $flonums)
|
||||
(except (ikarus) flonum->string string->flonum))
|
||||
|
||||
(define (flonum->string x)
|
||||
|
@ -22,7 +23,49 @@
|
|||
(foreign-call "ikrt_bytevector_to_flonum"
|
||||
(string->utf8-bytevector x))]
|
||||
[else
|
||||
(error 'string->flonum "~s is not a string" x)])))
|
||||
(error 'string->flonum "~s is not a string" x)]))
|
||||
|
||||
(define (flonum-bytes f)
|
||||
(unless (flonum? f)
|
||||
(error 'flonum-bytes "~s is not a flonum" f))
|
||||
(values
|
||||
($flonum-u8-ref f 0)
|
||||
($flonum-u8-ref f 1)
|
||||
($flonum-u8-ref f 2)
|
||||
($flonum-u8-ref f 3)
|
||||
($flonum-u8-ref f 4)
|
||||
($flonum-u8-ref f 5)
|
||||
($flonum-u8-ref f 6)
|
||||
($flonum-u8-ref f 7)))
|
||||
|
||||
(define (flonum-parts x)
|
||||
(unless (flonum? x)
|
||||
(error 'flonum-parts "~s is not a flonum" x))
|
||||
(let-values ([(b0 b1 b2 b3 b4 b5 b6 b7) (flonum-bytes x)])
|
||||
(values
|
||||
(zero? (fxlogand b0 128))
|
||||
(+ (fxsll (fxlogand b0 127) 4)
|
||||
(fxsra b1 4))
|
||||
(+ (+ b7 (fxsll b6 8) (fxsll b5 16))
|
||||
(* (+ b4
|
||||
(fxsll b3 8)
|
||||
(fxsll b2 16)
|
||||
(fxsll (fxlogand b1 #b1111) 24))
|
||||
(expt 2 24))))))
|
||||
|
||||
(define ($flonum->exact x)
|
||||
(let-values ([(pos? be m) (flonum-parts x)])
|
||||
(cond
|
||||
[(<= 1 be 2046) ; normalized flonum
|
||||
(* (if pos? 1 -1)
|
||||
(* (+ m (expt 2 52)) (expt 2 (- be 1075))))]
|
||||
[(= be 0)
|
||||
(* (if pos? 1 -1)
|
||||
(* m (expt 2 -1074)))]
|
||||
[else #f])))
|
||||
|
||||
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
@ -30,17 +73,18 @@
|
|||
(export + - * / zero? = < <= > >= add1 sub1 quotient remainder
|
||||
positive? expt gcd lcm numerator denominator exact-integer-sqrt
|
||||
quotient+remainder number->string string->number max
|
||||
exact->inexact)
|
||||
exact->inexact floor ceiling)
|
||||
(import
|
||||
(ikarus system $fx)
|
||||
(ikarus system $ratnums)
|
||||
(ikarus system $bignums)
|
||||
(ikarus system $chars)
|
||||
(ikarus system $strings)
|
||||
(only (ikarus flonums) $flonum->exact)
|
||||
(except (ikarus) + - * / zero? = < <= > >= add1 sub1 quotient
|
||||
remainder quotient+remainder number->string positive?
|
||||
string->number expt gcd lcm numerator denominator
|
||||
exact->inexact
|
||||
exact->inexact floor ceiling
|
||||
exact-integer-sqrt max))
|
||||
|
||||
(define (fixnum->flonum x)
|
||||
|
@ -943,7 +987,7 @@
|
|||
[(fixnum? m)
|
||||
(if ($fx>= m 0)
|
||||
(fxexpt n m)
|
||||
(error 'expt "power should be positive, got ~s" m))]
|
||||
(/ 1 (expt n (- m))))]
|
||||
[(bignum? m)
|
||||
(cond
|
||||
[(eq? n 0) 0]
|
||||
|
@ -953,11 +997,9 @@
|
|||
(if (even-bignum? m)
|
||||
1
|
||||
-1)
|
||||
(error 'expt "power should be positive, got ~s" m))]
|
||||
(/ 1 (expt n (- m))))]
|
||||
[else
|
||||
(if (positive-bignum? m)
|
||||
(error 'expt "(expt ~s ~s) is too big to compute" n m)
|
||||
(error 'expt "power should be positive, got ~s" m))])]
|
||||
(error 'expt "(expt ~s ~s) is too big to compute" n m)])]
|
||||
[else (error 'expt "~s is not a number" m)])))
|
||||
|
||||
(define quotient
|
||||
|
@ -1091,6 +1133,41 @@
|
|||
[(or (fixnum? x) (bignum? x)) 1]
|
||||
[else (error 'denominator "~s is not an exact integer" x)])))
|
||||
|
||||
|
||||
(define (floor x)
|
||||
(define (ratnum-floor x)
|
||||
(let ([n (numerator x)] [d (denominator x)])
|
||||
(let ([q (quotient n d)])
|
||||
(if (>= n 0) q (- q 1)))))
|
||||
(cond
|
||||
[(flonum? x)
|
||||
(let ([e (or ($flonum->exact x)
|
||||
(error 'floor "~s has no real value" x))])
|
||||
(cond
|
||||
[(ratnum? e) (ratnum-floor e)]
|
||||
[else e]))]
|
||||
[(ratnum? x) (ratnum-floor x)]
|
||||
[(or (fixnum? x) (bignum? x)) x]
|
||||
[else (error 'floor "~s is not a number" x)]))
|
||||
|
||||
(define (ceiling x)
|
||||
(define (ratnum-ceiling x)
|
||||
(let ([n (numerator x)] [d (denominator x)])
|
||||
(let ([q (quotient n d)])
|
||||
(if (< n 0) q (+ q 1)))))
|
||||
(cond
|
||||
[(flonum? x)
|
||||
(let ([e (or ($flonum->exact x)
|
||||
(error 'ceiling "~s has no real value" x))])
|
||||
(cond
|
||||
[(ratnum? e) (ratnum-ceiling e)]
|
||||
[else e]))]
|
||||
[(ratnum? x) (ratnum-ceiling x)]
|
||||
[(or (fixnum? x) (bignum? x)) x]
|
||||
[else (error 'ceiling "~s is not a number" x)]))
|
||||
|
||||
|
||||
|
||||
(define string->number
|
||||
(lambda (x)
|
||||
(define (convert-data str len pos? idx ac)
|
||||
|
|
|
@ -104,7 +104,8 @@
|
|||
[(eq? mode 'replace)
|
||||
(f x i j ($fxadd1 n) mode)]
|
||||
[else
|
||||
(error who "invalid byte sequence ~s ~s" b0 b1)]))]
|
||||
(error who "invalid byte sequence ~s ~s
|
||||
in idx ~s of ~s" b0 b1 i bv)]))]
|
||||
[(eq? mode 'ignore) n]
|
||||
[(eq? mode 'replace) ($fxadd1 n)]
|
||||
[else
|
||||
|
|
|
@ -395,6 +395,8 @@
|
|||
[max i r]
|
||||
[numerator i r]
|
||||
[denominator i r]
|
||||
[floor i r]
|
||||
[ceiling i r]
|
||||
[exact-integer-sqrt i r]
|
||||
[exact->inexact i r]
|
||||
[symbol? i r symbols]
|
||||
|
|
|
@ -1166,36 +1166,6 @@
|
|||
[(P s i) (K #t)]
|
||||
[(E s i) (nop)])
|
||||
|
||||
#;
|
||||
(define (assert-fixnum x)
|
||||
(record-case x
|
||||
[(constant i)
|
||||
(if (fixnum? i) (nop) (interrupt))]
|
||||
[else (interrupt-unless (cogen-pred-fixnum? x))]))
|
||||
#;
|
||||
(define (assert-string x)
|
||||
(record-case x
|
||||
[(constant s) (if (string? s) (nop) (interrupt))]
|
||||
[else (interrupt-unless (cogen-pred-string? x))]))
|
||||
#;
|
||||
(define-primop string-ref safe
|
||||
[(V s i)
|
||||
(seq*
|
||||
(assert-fixnum i)
|
||||
(assert-string s)
|
||||
(interrupt-unless (prm 'u< (T i) (cogen-value-$string-length s)))
|
||||
(cogen-value-$string-ref s i))]
|
||||
[(P s i)
|
||||
(seq*
|
||||
(assert-fixnum i)
|
||||
(assert-string s)
|
||||
(interrupt-unless (prm 'u< (T i) (cogen-value-$string-length s)))
|
||||
(K #t))]
|
||||
[(E s i)
|
||||
(seq*
|
||||
(assert-fixnum i)
|
||||
(assert-string s)
|
||||
(interrupt-unless (prm 'u< (T i) (cogen-value-$string-length s))))])
|
||||
|
||||
(define-primop $bytevector-set! unsafe
|
||||
[(E x i c)
|
||||
|
|
Loading…
Reference in New Issue