add_ratio_ratio fixed.
This commit is contained in:
parent
d7e0220674
commit
169afc9eb4
3 changed files with 53 additions and 68 deletions
|
|
@ -1,5 +1,27 @@
|
||||||
# State of Play
|
# State of Play
|
||||||
|
|
||||||
|
## 20260215
|
||||||
|
|
||||||
|
Both of yesterday's regressions are fixed. Memory problem still in much the
|
||||||
|
same state.
|
||||||
|
|
||||||
|
> Allocation summary: allocated 1210; deallocated 10; not deallocated 1200.
|
||||||
|
|
||||||
|
That left the add ratios problem which was deeper. I had unintended unterminated
|
||||||
|
recursion happening there. :-(
|
||||||
|
|
||||||
|
It burned through 74 cons pages each of 1,024 cons cells, total 76,800 cells,
|
||||||
|
and 19,153 stack frames. before it got there; and then threw the exception back
|
||||||
|
up through each of those 19,153 stack frames. But the actual exception message
|
||||||
|
was `Unrecognised tag value 0 ( )`, which is not enormously helpful.
|
||||||
|
|
||||||
|
However, once I had recognised what the problem was, it was quickly fixed, with
|
||||||
|
the added bonus that the new solution will automatically work for bignum
|
||||||
|
fractions once bignums are working.
|
||||||
|
|
||||||
|
So we're down to eight unit tests failing: the memory leak, one unimplemented
|
||||||
|
feature, and the bignum problem.
|
||||||
|
|
||||||
## 20260214
|
## 20260214
|
||||||
|
|
||||||
### Memory leaks
|
### Memory leaks
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* return, as a int64_t, the greatest common divisor of `m` and `n`,
|
* @brief return, as an int64_t, the greatest common divisor of `m` and `n`,
|
||||||
*/
|
*/
|
||||||
int64_t greatest_common_divisor( int64_t m, int64_t n ) {
|
int64_t greatest_common_divisor( int64_t m, int64_t n ) {
|
||||||
int o;
|
int o;
|
||||||
|
|
@ -39,7 +39,7 @@ int64_t greatest_common_divisor( int64_t m, int64_t n ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* return, as a int64_t, the least common multiple of `m` and `n`,
|
* @brief return, as an int64_t, the least common multiple of `m` and `n`,
|
||||||
*/
|
*/
|
||||||
int64_t least_common_multiple( int64_t m, int64_t n ) {
|
int64_t least_common_multiple( int64_t m, int64_t n ) {
|
||||||
return m / greatest_common_divisor( m, n ) * n;
|
return m / greatest_common_divisor( m, n ) * n;
|
||||||
|
|
@ -64,7 +64,7 @@ struct cons_pointer simplify_ratio( struct cons_pointer pointer ) {
|
||||||
|
|
||||||
if ( gcd > 1 ) {
|
if ( gcd > 1 ) {
|
||||||
if ( drrv / gcd == 1 ) {
|
if ( drrv / gcd == 1 ) {
|
||||||
result = acquire_integer( ddrv / gcd, NIL );
|
result = acquire_integer( (int64_t)(ddrv / gcd), NIL );
|
||||||
} else {
|
} else {
|
||||||
debug_printf( DEBUG_ARITH,
|
debug_printf( DEBUG_ARITH,
|
||||||
L"simplify_ratio: %ld/%ld => %ld/%ld\n",
|
L"simplify_ratio: %ld/%ld => %ld/%ld\n",
|
||||||
|
|
@ -91,61 +91,26 @@ struct cons_pointer simplify_ratio( struct cons_pointer pointer ) {
|
||||||
*/
|
*/
|
||||||
struct cons_pointer add_ratio_ratio( struct cons_pointer arg1,
|
struct cons_pointer add_ratio_ratio( struct cons_pointer arg1,
|
||||||
struct cons_pointer arg2 ) {
|
struct cons_pointer arg2 ) {
|
||||||
struct cons_pointer r, result;
|
struct cons_pointer r;
|
||||||
|
|
||||||
debug_print( L"\naadd_ratio_ratio: ", DEBUG_ARITH);
|
debug_print( L"\nadd_ratio_ratio: ", DEBUG_ARITH);
|
||||||
debug_print_object( arg1, DEBUG_ARITH);
|
debug_print_object( arg1, DEBUG_ARITH);
|
||||||
debug_print( L" + ", DEBUG_ARITH);
|
debug_print( L" + ", DEBUG_ARITH);
|
||||||
debug_print_object( arg2, DEBUG_ARITH);
|
debug_print_object( arg2, DEBUG_ARITH);
|
||||||
|
|
||||||
if ( ratiop( arg1 ) && ratiop( arg2 ) ) {
|
if ( ratiop( arg1 ) && ratiop( arg2 ) ) {
|
||||||
struct cons_space_object cell1 = pointer2cell( arg1 );
|
struct cons_space_object * cell1 = &pointer2cell( arg1 );
|
||||||
struct cons_space_object cell2 = pointer2cell( arg2 );
|
struct cons_space_object * cell2 = &pointer2cell( arg2 );
|
||||||
int64_t dd1v =
|
|
||||||
pointer2cell( cell1.payload.ratio.dividend ).payload.integer.value,
|
|
||||||
dd2v =
|
|
||||||
pointer2cell( cell2.payload.ratio.dividend ).payload.integer.value,
|
|
||||||
dr1v =
|
|
||||||
pointer2cell( cell1.payload.ratio.divisor ).payload.integer.value,
|
|
||||||
dr2v =
|
|
||||||
pointer2cell( cell2.payload.ratio.divisor ).payload.integer.value,
|
|
||||||
lcm = least_common_multiple( dr1v, dr2v ),
|
|
||||||
m1 = lcm / dr1v, m2 = lcm / dr2v;
|
|
||||||
|
|
||||||
debug_printf( DEBUG_ARITH, L"; lcm = %ld; m1 = %ld; m2 = %ld", lcm,
|
struct cons_pointer divisor = multiply_integers( cell1->payload.ratio.divisor, cell2->payload.ratio.divisor );
|
||||||
m1, m2 );
|
struct cons_pointer dividend = add_integers(
|
||||||
|
multiply_integers( cell1->payload.ratio.dividend,
|
||||||
if ( dr1v == dr2v ) {
|
cell2->payload.ratio.divisor),
|
||||||
r = make_ratio( acquire_integer( dd1v + dd2v, NIL ),
|
multiply_integers( cell2->payload.ratio.dividend,
|
||||||
cell1.payload.ratio.divisor );
|
cell1->payload.ratio.divisor));
|
||||||
} else {
|
r = make_ratio( dividend, divisor );
|
||||||
struct cons_pointer dd1vm = acquire_integer( dd1v * m1, NIL ),
|
|
||||||
dr1vm = acquire_integer( dr1v * m1, NIL ),
|
|
||||||
dd2vm = acquire_integer( dd2v * m2, NIL ),
|
|
||||||
dr2vm = acquire_integer( dr2v * m2, NIL ),
|
|
||||||
r1 = make_ratio( dd1vm, dr1vm ),
|
|
||||||
r2 = make_ratio( dd2vm, dr2vm );
|
|
||||||
|
|
||||||
r = add_ratio_ratio( r1, r2 );
|
|
||||||
|
|
||||||
if ( !eq( r, r1 ) ) {
|
|
||||||
dec_ref( r1 );
|
|
||||||
}
|
|
||||||
if ( !eq( r, r2 ) ) {
|
|
||||||
dec_ref( r2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* because the references on dd1vm, dr1vm, dd2vm and dr2vm were
|
|
||||||
* never incremented except when making r1 and r2, decrementing
|
|
||||||
* r1 and r2 should be enought to garbage collect them. */
|
|
||||||
}
|
|
||||||
|
|
||||||
result = simplify_ratio( r );
|
|
||||||
if ( !eq( r, result ) ) {
|
|
||||||
dec_ref( r );
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
result =
|
r =
|
||||||
throw_exception( make_cons( c_string_to_lisp_string
|
throw_exception( make_cons( c_string_to_lisp_string
|
||||||
( L"Shouldn't happen: bad arg to add_ratio_ratio" ),
|
( L"Shouldn't happen: bad arg to add_ratio_ratio" ),
|
||||||
make_cons( arg1,
|
make_cons( arg1,
|
||||||
|
|
@ -153,11 +118,11 @@ struct cons_pointer add_ratio_ratio( struct cons_pointer arg1,
|
||||||
NIL );
|
NIL );
|
||||||
}
|
}
|
||||||
|
|
||||||
debug_print( L" => ", DEBUG_ARITH );
|
debug_print( L"add_ratio_ratio => ", DEBUG_ARITH );
|
||||||
debug_print_object( result, DEBUG_ARITH );
|
debug_print_object( r, DEBUG_ARITH );
|
||||||
debug_print( L"\n", DEBUG_ARITH );
|
debug_print( L"\n", DEBUG_ARITH );
|
||||||
|
|
||||||
return result;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
return=0
|
result=0
|
||||||
|
|
||||||
#####################################################################
|
#####################################################################
|
||||||
# last 'smallnum' value:
|
# last 'smallnum' value:
|
||||||
# sbcl calculates (expt 2 59) => 576460752303423488
|
# sbcl calculates (expt 2 59) => 576460752303423488
|
||||||
expected='576460752303423488'
|
expected='576460752303423488'
|
||||||
|
|
||||||
output=`target/psse <<EOF
|
output=`target/psse 2>/dev/null <<EOF
|
||||||
(progn
|
(progn
|
||||||
(set! expt (lambda
|
(set! expt (lambda
|
||||||
(n x)
|
(n x)
|
||||||
|
|
@ -26,7 +26,7 @@ then
|
||||||
echo "OK"
|
echo "OK"
|
||||||
else
|
else
|
||||||
echo "Fail: expected '${expected}', got '${actual}'"
|
echo "Fail: expected '${expected}', got '${actual}'"
|
||||||
return=1
|
result=`echo "${result} + 1" | bc`
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#####################################################################
|
#####################################################################
|
||||||
|
|
@ -34,7 +34,7 @@ fi
|
||||||
# sbcl calculates (expt 2 60) => 1152921504606846976
|
# sbcl calculates (expt 2 60) => 1152921504606846976
|
||||||
expected='1152921504606846976'
|
expected='1152921504606846976'
|
||||||
|
|
||||||
output=`target/psse <<EOF
|
output=`target/psse 2>/dev/null <<EOF
|
||||||
(progn
|
(progn
|
||||||
(set! expt (lambda
|
(set! expt (lambda
|
||||||
(n x)
|
(n x)
|
||||||
|
|
@ -53,7 +53,7 @@ then
|
||||||
echo "OK"
|
echo "OK"
|
||||||
else
|
else
|
||||||
echo "Fail: expected '${expected}', got '${actual}'"
|
echo "Fail: expected '${expected}', got '${actual}'"
|
||||||
return=1
|
result=`echo "${result} + 1" | bc`
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#####################################################################
|
#####################################################################
|
||||||
|
|
@ -61,7 +61,7 @@ fi
|
||||||
# sbcl calculates (expt 2 61) => 2305843009213693952
|
# sbcl calculates (expt 2 61) => 2305843009213693952
|
||||||
expected='2305843009213693952'
|
expected='2305843009213693952'
|
||||||
|
|
||||||
output=`target/psse <<EOF
|
output=`target/psse 2>/dev/null <<EOF
|
||||||
(progn
|
(progn
|
||||||
(set! expt (lambda
|
(set! expt (lambda
|
||||||
(n x)
|
(n x)
|
||||||
|
|
@ -80,15 +80,13 @@ then
|
||||||
echo "OK"
|
echo "OK"
|
||||||
else
|
else
|
||||||
echo "Fail: expected '${expected}', got '${actual}'"
|
echo "Fail: expected '${expected}', got '${actual}'"
|
||||||
return=1
|
result=`echo "${result} + 1" | bc`
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# sbcl calculates (expt 2 64) => 18446744073709551616
|
# sbcl calculates (expt 2 64) => 18446744073709551616
|
||||||
expected='18446744073709551616'
|
expected='18446744073709551616'
|
||||||
|
|
||||||
output=`target/psse <<EOF
|
output=`target/psse 2>/dev/null <<EOF
|
||||||
(progn
|
(progn
|
||||||
(set! expt (lambda
|
(set! expt (lambda
|
||||||
(n x)
|
(n x)
|
||||||
|
|
@ -107,13 +105,13 @@ then
|
||||||
echo "OK"
|
echo "OK"
|
||||||
else
|
else
|
||||||
echo "Fail: expected '${expected}', got '${actual}'"
|
echo "Fail: expected '${expected}', got '${actual}'"
|
||||||
return=1
|
result=`echo "${result} + 1" | bc`
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# sbcl calculates (expt 2 65) => 36893488147419103232
|
# sbcl calculates (expt 2 65) => 36893488147419103232
|
||||||
expected='36893488147419103232'
|
expected='36893488147419103232'
|
||||||
|
|
||||||
output=`target/psse <<EOF
|
output=`target/psse 2>/dev/null <<EOF
|
||||||
(progn
|
(progn
|
||||||
(set! expt (lambda
|
(set! expt (lambda
|
||||||
(n x)
|
(n x)
|
||||||
|
|
@ -132,7 +130,7 @@ then
|
||||||
echo "OK"
|
echo "OK"
|
||||||
else
|
else
|
||||||
echo "Fail: expected '${expected}', got '${actual}'"
|
echo "Fail: expected '${expected}', got '${actual}'"
|
||||||
return=1
|
result=`echo "${result} + 1" | bc`
|
||||||
fi
|
fi
|
||||||
|
|
||||||
exit ${return}
|
exit ${result}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue