From 7c84cb433a257e25ff55b3d05a29722f09ccdf90 Mon Sep 17 00:00:00 2001 From: Simon Brooke Date: Sun, 16 Mar 2025 09:38:00 +0000 Subject: [PATCH] Changed from using bit-shifts to using arithmetic operators. More tests fail, but... --- lisp/fact.lisp | 2 +- src/arith/integer.c | 12 ++++++------ src/arith/peano.h | 4 +++- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/lisp/fact.lisp b/lisp/fact.lisp index 86d452a..17a7288 100644 --- a/lisp/fact.lisp +++ b/lisp/fact.lisp @@ -1,6 +1,6 @@ (set! fact (lambda (n) - "Compute the factorial of `n`, expected to be an integer." + "Compute the factorial of `n`, expected to be a natural number." (cond ((= n 1) 1) (t (* n (fact (- n 1))))))) diff --git a/src/arith/integer.c b/src/arith/integer.c index 0b4990a..7ca328f 100644 --- a/src/arith/integer.c +++ b/src/arith/integer.c @@ -71,7 +71,7 @@ struct cons_pointer make_integer( int64_t value, struct cons_pointer more ) { __int128_t cell_value( struct cons_pointer c, char op, bool is_first_cell ) { long int val = nilp( c ) ? 0 : pointer2cell( c ).payload.integer.value; - long int carry = is_first_cell ? 0 : ( MAX_INTEGER + 1 ); + long int carry = is_first_cell ? 0 : ( INT_CELL_BASE ); __int128_t result = ( __int128_t ) integerp( c ) ? ( val == 0 ) ? carry : val : op == '*' ? 1 : 0; @@ -106,15 +106,15 @@ __int128_t int128_to_integer( __int128_t val, if ( MAX_INTEGER >= val ) { carry = 0; } else { - carry = val >> INTEGER_BIT_SHIFT; + carry = val % INT_CELL_BASE; debug_printf( DEBUG_ARITH, L"int128_to_integer: 64 bit overflow; setting carry to %ld\n", ( int64_t ) carry ); - val &= MAX_INTEGER; + val /= INT_CELL_BASE; } struct cons_space_object *newc = &pointer2cell( new ); - newc->payload.integer.value = val; + newc->payload.integer.value = (int64_t)val; if ( integerp( less_significant ) ) { struct cons_space_object *lsc = &pointer2cell( less_significant ); @@ -136,7 +136,7 @@ struct cons_pointer make_integer_128( __int128_t val, less_significant = make_integer( ( long int ) val & MAX_INTEGER, less_significant ); - val = val >> INTEGER_BIT_SHIFT; + val = val * INT_CELL_BASE; } } while ( nilp( result ) ); @@ -361,7 +361,7 @@ struct cons_pointer integer_to_string( struct cons_pointer int_pointer, while ( accumulator > 0 || !nilp( next ) ) { if ( accumulator < MAX_INTEGER && !nilp( next ) ) { accumulator += - ( pointer2cell( next ).payload.integer.value << INTEGER_BIT_SHIFT ); + ( pointer2cell( next ).payload.integer.value % INT_CELL_BASE ); next = pointer2cell( next ).payload.integer.more; } int offset = ( int ) ( accumulator % base ); diff --git a/src/arith/peano.h b/src/arith/peano.h index eb53450..95c5013 100644 --- a/src/arith/peano.h +++ b/src/arith/peano.h @@ -21,7 +21,9 @@ * * So left shifting and right shifting by 60 bits is correct. */ -#define MAX_INTEGER ((__int128_t)0x0fffffffffffffffL) +#define MAX_INTEGER ((__int128_t)0x0fffffffffffffffL) +#define INT_CELL_BASE ((__int128_t)MAX_INTEGER + 1) // ((__int128_t)0x1000000000000000L) + /** * @brief Number of value bits in an integer cell *