Seems it was & wasn't the function, here's the updated version:
Code:
int bnum_compare( bnum_t const num, bnum_t const val ) {
int ret, nsb = 0, vsb = 0;
bit_t n, v;
PRINT_IF_TRUE( (ret = bnum_mem_chk(num)) != 0, return ret; )
PRINT_IF_TRUE( (ret = bnum_mem_chk(val)) != 0, return ret; )
n = num.width;
v = val.width;
if ( num.sig_bit ) {
n = bit_op_dec(n);
nsb = (num.value[n.node] & n.bit) ? 1 : 0;
}
if ( val.sig_bit ) {
v = bit_op_dec(v);
vsb = (num.value[v.node] & v.bit) ? 1 : 0;
}
ret = nsb - vsb;
if ( ret != 0 )
return -ret;
while ( n.b > v.b ) {
n = bit_op_dec(n);
ret = (num.value[n.node] & n.bit) ? 1 : 0;
if ( ret != vsb )
return (vsb == 0) ? 1 : -1;
}
while ( v.b > n.b ) {
v = bit_op_dec(v);
vsb = (val.value[v.node] & v.bit) ? 1 : 0;
if ( ret != nsb )
return (nsb == 0) ? -1 : 1;
}
while ( n.b > 0 ) {
n = bit_op_dec(n);
v = bit_op_dec(v);
ret = (num.value[n.node] & n.bit) ? 1 : 0;
ret -= (val.value[v.node] & v.bit) ? 1 : 0;
/* This line appears to be the problem */
if ( ret != 0 ) return (nsb == 0) ? ret : -ret;
}
return 0;
}
#define bnum_op_compare( NAME, OPERATOR ) \
int bnum_op_##NAME( bnum_t const num, bnum_t const val ) \
{ \
int ret = bnum_compare( num, val ); \
if ( ret < -1 || ret > 1 ) return ret; \
return ( ret OPERATOR 0 ); \
}
bnum_op_compare(eql,==)
bnum_op_compare(neq,!=)
bnum_op_compare(gth,<)
bnum_op_compare(gte,>=)
bnum_op_compare(lth,>)
bnum_op_compare(lte,<=)
#undef bnum_op_compare
As you'll notice at the bottom I had tried changing the comparsion of the bnum_op_gth() function to the opposite one would expect there and got the expected result, only for it to then fail at bnum_op_lth() despite using the same tactic (which techinically means the function is operating both correct and incorrectly, correct because one would expect that from the opposing operator but incorrect BECAUSE it's using the wrong operator)
Any ideas on what to do would be appreciated (btw I have tried returning ret as it is, still same problem, just different variation)
Edit: Was gonna edit my original output with this but can't do that, I modified comparison() to give a bit more info and put the correct operators in the bnum_op_*() set:
Code:
make run (in directory: /media/lee/ZXUIJI_1TB/github/code/bnum)
gcc -o ../bnum/cmp.o -c ../bnum/cmp.c
gcc -o ../code.elf ../print.o ../predef.o ../chk.o ../add.o ../code.o ../open.o ../mem_inc.o ../shut.o ../init_and_term.o ../get.o ../bnum/bit.o ../bnum/cmp.o ../bnum/math.o ../bnum/div.o
./../code.elf
Testing Integer Comparisons...
comparison( 846930886, '=', 1804289383 ) call 0
cycle_started 498; cycle_changed 499, cycle_stopped 500
num == val 0, 0
comparison( 1714636915, '!', 1681692777 ) call 1
cycle_started 502; cycle_changed 503, cycle_stopped 503
num != val 1, 1
comparison( 424238335, '>', 1957747793 ) call 2
cycle_started 505; cycle_changed 505, cycle_stopped 506
num >= val 0, 0
comparison( 1649760492, 'g', 719885386 ) call 3
cycle_started 507; cycle_changed 508, cycle_stopped 508
num > val 1, 0
../code.c:245: comparison() r != t
r = 0b00000000000000000000000000000001, num = 0b01100010010101010101100011101100
t = 0b00000000000000000000000000000000, val = 0b00101010111010001001010001001010
Numerical argument out of domain
../makefile:16: recipe for target 'run' failed
make: *** [run] Error 1
Compilation failed.