Much investigation of bignum problems
bignum multiply is still not working, but as bignum read and bignum divide depend on it, it's the problem to hit first.
This commit is contained in:
parent
000ae3c392
commit
0f8bc990f2
|
@ -5,4 +5,4 @@
|
|||
((= x 1) n)
|
||||
(t (* n (expt n (- x 1)))))))
|
||||
|
||||
(expt 2 65)
|
||||
(expt 2 60)
|
||||
|
|
48
lisp/scratchpad.lisp
Normal file
48
lisp/scratchpad.lisp
Normal file
|
@ -0,0 +1,48 @@
|
|||
(set! i
|
||||
(+
|
||||
10000000000000000000
|
||||
10000000000000000000
|
||||
10000000000000000000
|
||||
10000000000000000000
|
||||
10000000000000000000
|
||||
10000000000000000000
|
||||
10000000000000000000
|
||||
10000000000000000000
|
||||
10000000000000000000
|
||||
10000000000000000000))
|
||||
|
||||
(set! j (+ i i i i i i i i i i))
|
||||
|
||||
(set! k (+ j j j j j j j j j j))
|
||||
|
||||
(set! l (+ k k k k k k k k k k))
|
||||
|
||||
(set! m (+ l l l l l l l l l l))
|
||||
|
||||
(set! n (+ m m m m m m m m m m))
|
||||
|
||||
(set! o (+ n n n n n n n n n n))
|
||||
|
||||
(set! p (+ o o o o o o o o o o))
|
||||
|
||||
(set! q (+ p p p p p p p p p p))
|
||||
|
||||
(set! r (+ q q q q q q q q q q))
|
||||
|
||||
(set! s (+ r r r r r r r r r r))
|
||||
|
||||
(set! t (+ s s s s s s s s s s))
|
||||
|
||||
(set! u (+ t t t t t t t t t t))
|
||||
|
||||
(set! v (+ u u u u u u u u u u))
|
||||
|
||||
(set! x (+ v v v v v v v v v v))
|
||||
|
||||
(set! y (+ x x x x x x x x x x))
|
||||
|
||||
"we're OK to here: 10^36, which is below the 2^120 barrier so represented as two cells"
|
||||
(inspect (set! z (+ y y y y y y y y y y)))
|
||||
|
||||
"This blows up: 10^37, which is a three cell bignum."
|
||||
(inspect (+ z z z z z z z z z z))
|
84
lisp/scratchpad2.lisp
Normal file
84
lisp/scratchpad2.lisp
Normal file
|
@ -0,0 +1,84 @@
|
|||
"This demonstrates that although the print representation of three cell bignums blows up, the internal representation is sane"
|
||||
|
||||
"We start by adding 8 copies of 2^60 - i.e. the first two-cell integer"
|
||||
|
||||
(set! a
|
||||
(+
|
||||
1152921504606846976
|
||||
1152921504606846976
|
||||
1152921504606846976
|
||||
1152921504606846976
|
||||
1152921504606846976
|
||||
1152921504606846976
|
||||
1152921504606846976
|
||||
1152921504606846976))
|
||||
|
||||
"Then repeatedly add eight copies of the previous generation"
|
||||
|
||||
(set! b (+ a a a a a a a a))
|
||||
|
||||
(set! c (+ b b b b b b b b))
|
||||
|
||||
(set! d (+ c c c c c c c c))
|
||||
|
||||
(set! e (+ d d d d d d d d))
|
||||
|
||||
(set! f (+ e e e e e e e e))
|
||||
|
||||
(set! g (+ f f f f f f f f))
|
||||
|
||||
(set! h (+ g g g g g g g g))
|
||||
|
||||
(set! i (+ h h h h h h h h))
|
||||
|
||||
(set! j (+ i i i i i i i i))
|
||||
|
||||
(set! k (+ j j j j j j j j))
|
||||
|
||||
(set! l (+ k k k k k k k k))
|
||||
|
||||
(set! m (+ l l l l l l l l))
|
||||
|
||||
(set! n (+ m m m m m m m m))
|
||||
|
||||
(set! o (+ n n n n n n n n))
|
||||
|
||||
"p"
|
||||
(set! p (+ o o o o o o o o))
|
||||
|
||||
"q"
|
||||
(set! q (+ p p p p p p p p))
|
||||
|
||||
"r"
|
||||
(set! r (+ q q q q q q q q))
|
||||
|
||||
"s"
|
||||
(inspect
|
||||
(set! s (+ r r r r r r r r)))
|
||||
|
||||
"t - first three cell integer. Printing blows up here"
|
||||
(inspect
|
||||
(set! t (+ s s s s s s s s)))
|
||||
|
||||
"u"
|
||||
(inspect
|
||||
(set! u (+ t t t t t t t t)))
|
||||
|
||||
"v"
|
||||
(inspect
|
||||
(set! v (+ u u u u u u u u)))
|
||||
|
||||
"w"
|
||||
(inspect
|
||||
(set! w (+ v v v v v v v v)))
|
||||
|
||||
(inspect
|
||||
(set! x (+ w w w w w w w w)))
|
||||
|
||||
(inspect
|
||||
(set! y (+ x x x x x x x x)))
|
||||
|
||||
(inspect
|
||||
(set! z (+ y y y y y y y y)))
|
||||
|
||||
(inspect (+ z z z z z z z z))
|
|
@ -36,7 +36,7 @@
|
|||
/**
|
||||
* hexadecimal digits for printing numbers.
|
||||
*/
|
||||
const char * hex_digits = "0123456789ABCDEF";
|
||||
const char *hex_digits = "0123456789ABCDEF";
|
||||
|
||||
/*
|
||||
* Doctrine from here on in is that ALL integers are bignums, it's just
|
||||
|
@ -95,6 +95,21 @@ 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 );
|
||||
|
||||
__int128_t result = ( __int128_t ) integerp( c ) ?
|
||||
( val == 0 ) ? carry : val : op == '*' ? 1 : 0;
|
||||
debug_printf( DEBUG_ARITH,
|
||||
L"cell_value: raw value is %ld, op = '%c', is_first_cell = %s; returning ",
|
||||
val, op, is_first_cell ? "true" : "false" );
|
||||
debug_print_128bit( result, DEBUG_ARITH );
|
||||
debug_println( DEBUG_ARITH );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* internal workings of both `add_integers` and `multiply_integers` (and
|
||||
* possibly, later, other operations. Apply the operator `op` to the
|
||||
|
@ -106,26 +121,22 @@ struct cons_pointer make_integer( int64_t value, struct cons_pointer more ) {
|
|||
* up significantly WRONG, but the value in the more significant cell
|
||||
* ends up correct. */
|
||||
struct cons_pointer operate_on_integers( struct cons_pointer a,
|
||||
struct cons_pointer b,
|
||||
char op) {
|
||||
struct cons_pointer b, char op ) {
|
||||
struct cons_pointer result = NIL;
|
||||
struct cons_pointer cursor = NIL;
|
||||
__int128_t carry = 0;
|
||||
bool is_first_cell = true;
|
||||
|
||||
if ( integerp( a ) && integerp( b ) ) {
|
||||
debug_print( L"operate_on_integers: \n", DEBUG_ARITH );
|
||||
debug_dump_object( a, DEBUG_ARITH );
|
||||
debug_printf( DEBUG_ARITH, L" %c \n", op);
|
||||
debug_printf( DEBUG_ARITH, L" %c \n", op );
|
||||
debug_dump_object( b, DEBUG_ARITH );
|
||||
debug_println( DEBUG_ARITH );
|
||||
|
||||
while ( !nilp( a ) || !nilp( b ) || carry != 0 ) {
|
||||
__int128_t av =
|
||||
( __int128_t ) integerp( a ) ? pointer2cell( a ).
|
||||
payload.integer.value : op == '*' ? 1 : 0;
|
||||
__int128_t bv =
|
||||
( __int128_t ) integerp( b ) ? pointer2cell( b ).
|
||||
payload.integer.value : op == '*' ? 1 : 0;
|
||||
__int128_t av = cell_value( a, op, is_first_cell );
|
||||
__int128_t bv = cell_value( b, op, is_first_cell );
|
||||
|
||||
/* slightly dodgy. `MAX_INTEGER` is substantially smaller than `LONG_MAX`, and
|
||||
* `LONG_MAX * LONG_MAX` =~ the maximum value for `__int128_t`. So if the carry
|
||||
|
@ -135,24 +146,25 @@ struct cons_pointer operate_on_integers( struct cons_pointer a,
|
|||
*/
|
||||
__int128_t rv = NAN;
|
||||
|
||||
switch (op) {
|
||||
switch ( op ) {
|
||||
case '*':
|
||||
rv = av * bv * ((carry == 0) ? 1 : carry);
|
||||
rv = av * bv * ( ( carry == 0 ) ? 1 : carry );
|
||||
break;
|
||||
case '+':
|
||||
rv = av + bv + carry;
|
||||
break;
|
||||
}
|
||||
|
||||
debug_printf( DEBUG_ARITH, L"operate_on_integers: op = '%c'; av = ", op);
|
||||
debug_print_128bit( av, 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"\n", DEBUG_ARITH);
|
||||
debug_printf( DEBUG_ARITH,
|
||||
L"operate_on_integers: op = '%c'; av = ", op );
|
||||
debug_print_128bit( av, 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"\n", DEBUG_ARITH );
|
||||
|
||||
|
||||
if ( MAX_INTEGER >= rv ) {
|
||||
|
@ -186,6 +198,7 @@ struct cons_pointer operate_on_integers( struct cons_pointer a,
|
|||
|
||||
a = pointer2cell( a ).payload.integer.more;
|
||||
b = pointer2cell( b ).payload.integer.more;
|
||||
is_first_cell = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -203,7 +216,7 @@ struct cons_pointer operate_on_integers( struct cons_pointer a,
|
|||
struct cons_pointer add_integers( struct cons_pointer a,
|
||||
struct cons_pointer b ) {
|
||||
|
||||
return operate_on_integers(a, b, '+');
|
||||
return operate_on_integers( a, b, '+' );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -212,7 +225,7 @@ struct cons_pointer add_integers( struct cons_pointer a,
|
|||
*/
|
||||
struct cons_pointer multiply_integers( struct cons_pointer a,
|
||||
struct cons_pointer b ) {
|
||||
return operate_on_integers( a, b, '*');
|
||||
return operate_on_integers( a, b, '*' );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -221,7 +234,7 @@ struct cons_pointer multiply_integers( struct cons_pointer a,
|
|||
struct cons_pointer integer_to_string_add_digit( int digit, int digits,
|
||||
struct cons_pointer tail ) {
|
||||
digits++;
|
||||
wint_t character = btowc(hex_digits[digit]);
|
||||
wint_t character = btowc( hex_digits[digit] );
|
||||
return ( digits % 3 == 0 ) ?
|
||||
make_string( L',', make_string( character,
|
||||
tail ) ) :
|
||||
|
@ -239,6 +252,11 @@ struct cons_pointer integer_to_string_add_digit( int digit, int digits,
|
|||
* when we get to the last digit from one integer cell, we have potentially
|
||||
* to be looking to the next. H'mmmm.
|
||||
*/
|
||||
/*
|
||||
* TODO: this blows up when printing three-cell integers, but works fine
|
||||
* for two-cell. What's happening is that when we cross the barrier we
|
||||
* SHOULD print 2^120, but what we actually print is 2^117. H'mmm.
|
||||
*/
|
||||
struct cons_pointer integer_to_string( struct cons_pointer int_pointer,
|
||||
int base ) {
|
||||
struct cons_pointer result = NIL;
|
||||
|
@ -253,24 +271,27 @@ struct cons_pointer integer_to_string( struct cons_pointer int_pointer,
|
|||
while ( accumulator > 0 || !nilp( integer.payload.integer.more ) ) {
|
||||
if ( !nilp( integer.payload.integer.more ) ) {
|
||||
integer = pointer2cell( integer.payload.integer.more );
|
||||
accumulator +=
|
||||
accumulator += integer.payload.integer.value == 0 ?
|
||||
MAX_INTEGER :
|
||||
( llabs( integer.payload.integer.value ) *
|
||||
( MAX_INTEGER + 1 ) );
|
||||
debug_print
|
||||
( L"integer_to_string: crossing cell boundary, accumulator is: ",
|
||||
DEBUG_IO );
|
||||
debug_print_128bit( accumulator, DEBUG_IO );
|
||||
debug_println( DEBUG_IO );
|
||||
}
|
||||
|
||||
debug_printf( DEBUG_IO,
|
||||
L"integer_to_string: accumulator is %ld\n:",
|
||||
accumulator );
|
||||
do {
|
||||
int offset = (int)(accumulator % base);
|
||||
int offset = ( int ) ( accumulator % base );
|
||||
debug_printf( DEBUG_IO,
|
||||
L"integer_to_string: digit is %ld, hexadecimal is %c\n:",
|
||||
offset,
|
||||
hex_digits[offset] );
|
||||
L"integer_to_string: digit is %ld, hexadecimal is %c, accumulator is: ",
|
||||
offset, hex_digits[offset] );
|
||||
debug_print_128bit( accumulator, DEBUG_IO );
|
||||
debug_println( DEBUG_IO );
|
||||
|
||||
result =
|
||||
integer_to_string_add_digit( offset, digits++,
|
||||
result );
|
||||
integer_to_string_add_digit( offset, digits++, result );
|
||||
accumulator = accumulator / base;
|
||||
} while ( accumulator > base );
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ bool zerop( struct cons_pointer arg ) {
|
|||
switch ( cell.tag.value ) {
|
||||
case INTEGERTV:
|
||||
result = cell.payload.integer.value == 0 &&
|
||||
nilp(cell.payload.integer.more);
|
||||
nilp( cell.payload.integer.more );
|
||||
break;
|
||||
case RATIOTV:
|
||||
result = zerop( cell.payload.ratio.dividend );
|
||||
|
|
19
src/debug.c
19
src/debug.c
|
@ -46,23 +46,24 @@ void debug_print( wchar_t *message, int level ) {
|
|||
* stolen from https://stackoverflow.com/questions/11656241/how-to-print-uint128-t-number-using-gcc
|
||||
*/
|
||||
void debug_print_128bit( __int128_t n, int level ) {
|
||||
#ifdef DEBUG
|
||||
#ifdef DEBUG
|
||||
if ( level & verbosity ) {
|
||||
if (n == 0) {
|
||||
fwprintf(stderr, L"0");
|
||||
if ( n == 0 ) {
|
||||
fwprintf( stderr, L"0" );
|
||||
} else {
|
||||
char str[40] = {0}; // log10(1 << 128) + '\0'
|
||||
char *s = str + sizeof(str) - 1; // start at the end
|
||||
while (n != 0) {
|
||||
if (s == str) return; // never happens
|
||||
char str[40] = { 0 }; // log10(1 << 128) + '\0'
|
||||
char *s = str + sizeof( str ) - 1; // start at the end
|
||||
while ( n != 0 ) {
|
||||
if ( s == str )
|
||||
return; // never happens
|
||||
|
||||
*--s = "0123456789"[n % 10]; // save last digit
|
||||
n /= 10; // drop it
|
||||
}
|
||||
fwprintf(stderr, L"%s", s);
|
||||
fwprintf( stderr, L"%s", s );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -180,14 +180,15 @@ struct cons_pointer read_number( struct stack_frame *frame,
|
|||
|
||||
for ( c = initial; iswdigit( c )
|
||||
|| c == L'.' || c == L'/' || c == L','; c = fgetwc( input ) ) {
|
||||
switch (c) {
|
||||
switch ( c ) {
|
||||
case L'.':
|
||||
if ( seen_period || !nilp( dividend ) ) {
|
||||
return throw_exception( c_string_to_lisp_string
|
||||
( L"Malformed number: too many periods" ),
|
||||
frame_pointer );
|
||||
} else {
|
||||
debug_print(L"read_number: decimal point seen\n", DEBUG_IO);
|
||||
debug_print( L"read_number: decimal point seen\n",
|
||||
DEBUG_IO );
|
||||
seen_period = true;
|
||||
}
|
||||
break;
|
||||
|
@ -197,13 +198,14 @@ struct cons_pointer read_number( struct stack_frame *frame,
|
|||
( L"Malformed number: dividend of rational must be integer" ),
|
||||
frame_pointer );
|
||||
} else {
|
||||
debug_print(L"read_number: ratio slash seen\n", DEBUG_IO);
|
||||
debug_print( L"read_number: ratio slash seen\n",
|
||||
DEBUG_IO );
|
||||
dividend = result;
|
||||
|
||||
result = make_integer( 0, NIL );
|
||||
}
|
||||
break;
|
||||
case L',' :
|
||||
case L',':
|
||||
// silently ignore it.
|
||||
break;
|
||||
default:
|
||||
|
@ -212,9 +214,10 @@ struct cons_pointer read_number( struct stack_frame *frame,
|
|||
NIL ) );
|
||||
|
||||
debug_printf( DEBUG_IO,
|
||||
L"read_number: added character %c, result now ", c );
|
||||
debug_print_object( result, DEBUG_IO);
|
||||
debug_print( L"\n", DEBUG_IO);
|
||||
L"read_number: added character %c, result now ",
|
||||
c );
|
||||
debug_print_object( result, DEBUG_IO );
|
||||
debug_print( L"\n", DEBUG_IO );
|
||||
|
||||
if ( seen_period ) {
|
||||
places_of_decimals++;
|
||||
|
@ -228,7 +231,7 @@ struct cons_pointer read_number( struct stack_frame *frame,
|
|||
ungetwc( c, input );
|
||||
|
||||
if ( seen_period ) {
|
||||
debug_print(L"read_number: converting result to real\n", DEBUG_IO);
|
||||
debug_print( L"read_number: converting result to real\n", DEBUG_IO );
|
||||
struct cons_pointer div = make_ratio( frame_pointer, result,
|
||||
make_integer( powl
|
||||
( to_long_double
|
||||
|
@ -241,12 +244,13 @@ struct cons_pointer read_number( struct stack_frame *frame,
|
|||
|
||||
dec_ref( div );
|
||||
} else if ( integerp( dividend ) ) {
|
||||
debug_print(L"read_number: converting result to ratio\n", DEBUG_IO);
|
||||
debug_print( L"read_number: converting result to ratio\n", DEBUG_IO );
|
||||
result = make_ratio( frame_pointer, dividend, result );
|
||||
}
|
||||
|
||||
if ( neg ) {
|
||||
debug_print(L"read_number: converting result to negative\n", DEBUG_IO);
|
||||
debug_print( L"read_number: converting result to negative\n",
|
||||
DEBUG_IO );
|
||||
|
||||
result = negative( frame_pointer, result );
|
||||
}
|
||||
|
|
|
@ -5,12 +5,12 @@
|
|||
# (right on the boundary)
|
||||
a=1152921504606846975
|
||||
b=1
|
||||
expected='1152921504606846976'
|
||||
output=`echo "(+ $a $b)" | target/psse -v 2 2>psse.log`
|
||||
c=`echo "$a + $b" | bc`
|
||||
expected='t'
|
||||
output=`echo "(= (+ $a $b) $c)" | target/psse -v 2 2>psse.log`
|
||||
|
||||
actual=`echo $output |\
|
||||
tail -1 |\
|
||||
sed 's/\,//g'`
|
||||
tail -1`
|
||||
|
||||
echo -n "adding $a to $b: "
|
||||
if [ "${expected}" = "${actual}" ]
|
||||
|
@ -36,8 +36,9 @@ fi
|
|||
# (just over the boundary)
|
||||
a='1152921504606846976'
|
||||
b=1
|
||||
expected='1152921504606846977'
|
||||
output=`echo "(+ $a $b)" | target/psse -v 2 2>psse.log`
|
||||
c=`echo "$a + $b" | bc`
|
||||
expected='t'
|
||||
output=`echo "(= (+ $a $b) $c)" | target/psse -v 2 2>psse.log`
|
||||
|
||||
actual=`echo $output |\
|
||||
tail -1 |\
|
||||
|
@ -62,13 +63,15 @@ else
|
|||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
#####################################################################
|
||||
# add a bignum and a smallnum to produce a bignum
|
||||
# (just over the boundary)
|
||||
a='1152921504606846977'
|
||||
b=1
|
||||
expected='1152921504606846978'
|
||||
output=`echo "(+ $a $b)" | target/psse -v 2 2>psse.log`
|
||||
c=`echo "$a + $b" | bc`
|
||||
expected='t'
|
||||
output=`echo "(= (+ $a $b) $c)" | target/psse -v 2 2>psse.log`
|
||||
|
||||
actual=`echo $output |\
|
||||
tail -1 |\
|
||||
|
@ -98,8 +101,9 @@ fi
|
|||
# (just over the boundary)
|
||||
a=1
|
||||
b=1152921504606846977
|
||||
expected='1152921504606846978'
|
||||
output=`echo "(+ $a $b)" | target/psse -v 2 2>psse.log`
|
||||
c=`echo "$a + $b" | bc`
|
||||
expected='t'
|
||||
output=`echo "(= (+ $a $b) $c)" | target/psse -v 2 2>psse.log`
|
||||
|
||||
actual=`echo $output |\
|
||||
tail -1 |\
|
||||
|
@ -124,12 +128,14 @@ else
|
|||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
#####################################################################
|
||||
# add two bignums to produce a bignum
|
||||
a=10000000000000000000
|
||||
b=10000000000000000000
|
||||
expected='20000000000000000000'
|
||||
output=`echo "(+ $a $b)" | target/psse -v 2 2>psse.log`
|
||||
c=`echo "$a + $b" | bc`
|
||||
expected='t'
|
||||
output=`echo "(= (+ $a $b) $c)" | target/psse -v 2 2>psse.log`
|
||||
|
||||
actual=`echo $output |\
|
||||
tail -1 |\
|
||||
|
@ -154,13 +160,15 @@ else
|
|||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
#####################################################################
|
||||
# add a smallnum and a two-cell bignum to produce a three-cell bignum
|
||||
# (just over the boundary)
|
||||
a=1
|
||||
b=1329227995784915872903807060280344576
|
||||
expected='1329227995784915872903807060280344577'
|
||||
output=`echo "(+ $a $b)" | target/psse -v 2 2>psse.log`
|
||||
c=`echo "$a + $b" | bc`
|
||||
expected='t'
|
||||
output=`echo "(= (+ $a $b) $c)" | target/psse -v 2 2>psse.log`
|
||||
|
||||
actual=`echo $output |\
|
||||
tail -1 |\
|
||||
|
@ -185,3 +193,36 @@ else
|
|||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
#####################################################################
|
||||
# This currently fails:
|
||||
# (= (+ 1 3064991081731777716716694054300618367237478244367204352)
|
||||
# 3064991081731777716716694054300618367237478244367204353)
|
||||
a=1
|
||||
b=3064991081731777716716694054300618367237478244367204352
|
||||
c=`echo "$a + $b" | bc`
|
||||
expected='t'
|
||||
output=`echo "(= (+ $a $b) $c)" | target/psse -v 2 2>psse.log`
|
||||
|
||||
actual=`echo $output |\
|
||||
tail -1 |\
|
||||
sed 's/\,//g'`
|
||||
|
||||
echo -n "adding $a to $b: "
|
||||
if [ "${expected}" = "${actual}" ]
|
||||
then
|
||||
echo "OK"
|
||||
else
|
||||
echo "Fail: expected '${expected}', got '${actual}'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -n "checking a bignum was created: "
|
||||
grep 'BIGNUM!' psse.log > /dev/null
|
||||
if [ $? -eq "0" ]
|
||||
then
|
||||
echo "OK"
|
||||
else
|
||||
echo "Fail"
|
||||
exit 1
|
||||
fi
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
# Not really a unit test, but a check to see where bignum addition breaks
|
||||
|
||||
broken=0
|
||||
i=1152921506900200000
|
||||
i=11529215046068469750
|
||||
# we've already proven we can successfullu get up to here
|
||||
increment=10000
|
||||
increment=1
|
||||
|
||||
while [ $broken -eq "0" ]
|
||||
do
|
Loading…
Reference in a new issue