Woohoo! Actual goddamned progress! Multiply might be working!
Print definitely isn't!
This commit is contained in:
parent
3c545a90e8
commit
71354d0f86
|
@ -216,6 +216,27 @@ struct cons_pointer base_partial( int depth ) {
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* destructively modify this `partial` by appending this `digit`.
|
||||
*/
|
||||
struct cons_pointer append_digit( struct cons_pointer partial, struct cons_pointer digit) {
|
||||
struct cons_pointer c = partial;
|
||||
struct cons_pointer result = partial;
|
||||
|
||||
if (nilp( partial)) {
|
||||
result = digit;
|
||||
} else {
|
||||
while ( !nilp( pointer2cell(c).payload.integer.more)) {
|
||||
c = pointer2cell(c).payload.integer.more;
|
||||
}
|
||||
|
||||
(&pointer2cell(c))->payload.integer.more = digit;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return a pointer to an integer representing the product of the integers
|
||||
* pointed to by `a` and `b`. If either isn't an integer, will return nil.
|
||||
|
@ -226,10 +247,10 @@ struct cons_pointer base_partial( int depth ) {
|
|||
*/
|
||||
struct cons_pointer multiply_integers( struct cons_pointer a,
|
||||
struct cons_pointer b ) {
|
||||
struct cons_pointer result = NIL;
|
||||
struct cons_pointer result = make_integer( 0, NIL);
|
||||
bool neg = is_negative( a ) != is_negative( b );
|
||||
bool is_first_b = true;
|
||||
int oom = -1;
|
||||
int i = 0;
|
||||
|
||||
debug_print( L"multiply_integers: a = ", DEBUG_ARITH );
|
||||
debug_print_object( a, DEBUG_ARITH );
|
||||
|
@ -238,60 +259,54 @@ struct cons_pointer multiply_integers( struct cons_pointer a,
|
|||
debug_println( DEBUG_ARITH );
|
||||
|
||||
if ( integerp( a ) && integerp( b ) ) {
|
||||
while ( !nilp( b ) ) {
|
||||
bool is_first_d = true;
|
||||
struct cons_pointer d = a;
|
||||
struct cons_pointer partial = base_partial( ++oom );
|
||||
/* for each digit in a, starting with the least significant (ai) */
|
||||
|
||||
for ( struct cons_pointer ai = a; !nilp( ai );
|
||||
ai = pointer2cell(ai).payload.integer.more) {
|
||||
/* set carry to 0 */
|
||||
__int128_t carry = 0;
|
||||
|
||||
while ( !nilp( d ) || carry != 0 ) {
|
||||
partial = make_integer( 0, partial );
|
||||
struct cons_pointer new = NIL;
|
||||
__int128_t dv = cell_value( d, '+', is_first_d );
|
||||
__int128_t bv = cell_value( b, '+', is_first_b );
|
||||
/* set least significant digits for result ri for this iteration
|
||||
* to i zeros */
|
||||
struct cons_pointer ri = base_partial( i++ );
|
||||
|
||||
__int128_t rv = ( dv * bv ) + carry;
|
||||
/* for each digit in b, starting with the least significant (bj) */
|
||||
for ( struct cons_pointer bj = b; !nilp( bj );
|
||||
bj = pointer2cell(bj).payload.integer.more) {
|
||||
|
||||
debug_print( L"multiply_integers: d = ", DEBUG_ARITH );
|
||||
debug_print_object( d, DEBUG_ARITH );
|
||||
debug_print( L"; dv = ", DEBUG_ARITH );
|
||||
debug_print_128bit( dv, DEBUG_ARITH );
|
||||
debug_print( L"; bv = ", DEBUG_ARITH );
|
||||
debug_print_128bit( bv, DEBUG_ARITH );
|
||||
debug_print( L"; carry = ", DEBUG_ARITH );
|
||||
debug_print_128bit( carry, DEBUG_ARITH );
|
||||
debug_print( L"; rv = ", DEBUG_ARITH );
|
||||
debug_print_128bit( rv, DEBUG_ARITH );
|
||||
debug_print( L"; acc = ", DEBUG_ARITH );
|
||||
debug_printf( DEBUG_ARITH,
|
||||
L"multiply_integers: a[i] = %Ld, b[j] = %Ld, i = %d\n",
|
||||
pointer2cell(ai).payload.integer.value,
|
||||
pointer2cell(bj).payload.integer.value, i);
|
||||
|
||||
/* multiply ai with bj and add the carry, resulting in a
|
||||
* value xj which may exceed one digit */
|
||||
__int128_t xj = pointer2cell(ai).payload.integer.value *
|
||||
pointer2cell(bj).payload.integer.value;
|
||||
xj += carry;
|
||||
|
||||
/* if xj exceeds one digit, break it into the digit dj and
|
||||
* the carry */
|
||||
carry = xj >> 60;
|
||||
struct cons_pointer dj = make_integer( xj & MAX_INTEGER, NIL);
|
||||
|
||||
/* destructively modify ri by appending dj */
|
||||
ri = append_digit( ri, dj);
|
||||
} /* end for bj */
|
||||
|
||||
/* if carry is not equal to zero, append it as a final digit
|
||||
* to ri */
|
||||
if (carry != 0) {
|
||||
ri = append_digit( ri, make_integer( carry, NIL));
|
||||
}
|
||||
|
||||
/* add ri to result */
|
||||
result = add_integers( result, ri);
|
||||
|
||||
debug_print( L"multiply_integers: result is ", DEBUG_ARITH );
|
||||
debug_print_object( result, DEBUG_ARITH );
|
||||
debug_print( L"; partial = ", DEBUG_ARITH );
|
||||
debug_print_object( partial, DEBUG_ARITH );
|
||||
debug_print( L"\n", DEBUG_ARITH );
|
||||
|
||||
new = make_integer_128( rv, base_partial( oom ) );
|
||||
|
||||
if ( zerop( partial ) ) {
|
||||
partial = new;
|
||||
} else {
|
||||
partial = add_integers( partial, new );
|
||||
}
|
||||
|
||||
d = integerp( d ) ? pointer2cell( d ).payload.integer.
|
||||
more : NIL;
|
||||
is_first_d = false;
|
||||
}
|
||||
|
||||
if ( nilp( result ) || zerop( result ) ) {
|
||||
result = partial;
|
||||
} else {
|
||||
struct cons_pointer old = result;
|
||||
result = add_integers( partial, result );
|
||||
//if (!eq(result, old)) dec_ref(old);
|
||||
//if (!eq(result, partial)) dec_ref(partial);
|
||||
}
|
||||
b = pointer2cell( b ).payload.integer.more;
|
||||
is_first_b = false;
|
||||
}
|
||||
debug_println( DEBUG_ARITH );
|
||||
} /* end for ai */
|
||||
}
|
||||
|
||||
debug_print( L"multiply_integers returning: ", DEBUG_ARITH );
|
||||
|
|
|
@ -163,7 +163,7 @@ struct cons_pointer print( URL_FILE * output, struct cons_pointer pointer ) {
|
|||
print_list( output, pointer );
|
||||
break;
|
||||
case EXCEPTIONTV:
|
||||
url_fwuts( L"\nException: ", output );
|
||||
url_fputws( L"\nException: ", output );
|
||||
dump_stack_trace( output, pointer );
|
||||
break;
|
||||
case FUNCTIONTV:
|
||||
|
|
Loading…
Reference in a new issue