Relevant output (or at least what I deem relevant, stops at division because result is different from expected so look at bottom to start with):
Code:
...
num >= val 0, 0
comparison( 1649760492, 'g', 719885386 ) call 3
cycle_started 1202; cycle_changed 1203, cycle_stopped 1205
num > val 1, 1
comparison( 1189641421, '<', 596516649 ) call 4
cycle_started 1208; cycle_changed 1209, cycle_stopped 1211
num <= val 0, 0
comparison( 1350490027, 'l', 1025202362 ) call 5
cycle_started 1214; cycle_changed 1215, cycle_stopped 1217
num < val 0, 0
Testing Single Integer Operations...
...
operation1('+',2044897763) call 2
cycle_started 1234, cycle_changed 1235, cycle_stopped 1236
++num 2044897764, 2044897764
...
Testing Double Integer Operations...
...
num << val -1782885184, -1782885184
operation2(-233665123,'>',5) call 5
cycle_started 1298, cycle_changed 1299, cycle_stopped 1307
...
operation2(-2089018456,'-',1059961393) call 10
cycle_started 1380, cycle_changed 1381, cycle_stopped 1385
num - val 1145987447, 1145987447
operation2(-1656478042,'/',5) call 11
cycle_started 1389, cycle_changed 1390, cycle_stopped 1399
num / val -331295608, 0
r(int) = 0b11101100010000001101010010001000, num(int) = 0b10011101010001000010011010100110
t(bnum_t) = 0b00000000000000000000000000000000, val(int) = 0b00000000000000000000000000000101
Numerical argument out of domain
../makefile:16: recipe for target 'run' failed
make: *** [run] Error 1
Compilation failed.
Objects:
Code:
#if 0
typedef ub bitn_t;
#define BITN_LAST_BIT DB_MIN
#else
typedef uq bitn_t;
#define BITN_LAST_BIT DQ_MIN
#endif
typedef struct bit {
bitn_t bit;
size_t b;
size_t node;
} bit_t;
#define bit_init 1,0,0
typedef struct bnum_cmp {
int err;
int ret;
bit_t n;
bit_t v;
} bnum_cmp_t;
typedef struct bnum {
union {
array_t array;
bitn_t *value;
};
bit_t start, width;
size_t sig_bit : 1;
size_t lendian : 1;
size_t pendian : 1;
/* TODO: Find name for the variant this placeholder represents */
size_t _endian : 1;
size_t bendian : 1;
} bnum_t;
Function (plus the reliant functions)
Code:
int bnum_divide( bnum_t num, bnum_t const val, bnum_t quo ) {
int ret;
bnum_t seg = num;
size_t width = 0;
bit_t n, v;
bool carry;
if ( num.sig_bit != quo.sig_bit ) {
puts("bnum_divide() num.sig_bit != quo.sig_bit");
return EINVAL;
}
quo.sig_bit = 0;
ret = bnum_op_min(quo);
quo.sig_bit = num.sig_bit;
if ( ret != 0 ) return ret;
if ( bnum_op_nil(val) ) {
num.sig_bit = 0;
ret = bnum_op_min( num );
num.sig_bit = quo.sig_bit;
puts("bnum_divide() val == 0");
return ret;
}
seg.start = bit_op_dec(seg.width);
seg.width.b = 1;
seg.start.b = 0;
while ( bnum_op_gte( num, val ) ) {
#if 0
while
#else
if
#endif
( bnum_op_gte(seg,val) ) {
/* Move quotiant width many bits */
bnum_op_shl_z(quo,width);
#if 0
bnum_op_inc(quo);
#else
quo.value[0] |= 1;
#endif
/* Subtract from mum */
width = (seg.width.b < val.width.b) ? seg.width.b : val.width.b;
for
(
carry = 0, n = seg.start, v = val.start;
n.b < width;
n = bit_op_inc(n), v = bit_op_inc(v)
)
{
if ( carry ) {
if ( seg.value[n.node] & n.bit ) {
seg.value[n.node] ^= n.bit;
carry = 0;
}
else
seg.value[n.node] |= n.bit;
}
if ( val.value[v.node] & v.bit ) {
if ( seg.value[n.node] & n.bit )
seg.value[n.node] ^= n.bit;
else {
seg.value[n.node] |= n.bit;
carry = 1;
}
}
}
if ( carry ) {
for ( ; n.b < seg.width.b; n = bit_op_inc(n) ) {
seg.value[n.node] ^= n.bit;
if ( seg.value[n.node] & n.bit ) {
carry = 0;
break;
}
}
}
/* Reset width */
width = 0;
}
++width;
seg.start = bit_op_dec(seg.start);
seg.width.b++;
}
return bnum_op_shl_z(quo,width);
}
int bnum_op_div( bnum_t num, bnum_t const val ) {
int ret = bnum_mem_chk(num);
bnum_t cpy = num;
if ( ret != 0 ) return ret;
cpy.value = malloc( num.array.bytes );
if ( cpy.value ) {
ret = bnum_divide( num, val, cpy );
if ( ret != 0 ) {
free( cpy.value );
return ret;
}
ret = bnum_op_cpy( num, cpy );
free( cpy.value );
return ret;
}
return ENOMEM;
}
int bnum_op_mod( bnum_t num, bnum_t const val ) {
int ret = bnum_mem_chk(num);
bnum_t cpy = num;
if ( ret != 0 ) return ret;
cpy.value = malloc( num.array.bytes );
if ( cpy.value ) {
ret = bnum_divide( num, val, cpy );
free( cpy.value );
return ret;
}
return ENOMEM;
}
Just in case you want/need to look, the comparison functions:
Code:
bnum_cmp_t bnum_compare( bnum_t const num, bnum_t const val ) {
bnum_cmp_t c = {0};
int nerr = bnum_mem_chk(num), verr = bnum_mem_chk(val);
if ( nerr != 0 ) {
c.err = nerr;
if ( verr == 0 )
c.ret = -1;
goto bnum_compare_done;
}
else if ( verr != 0 ) {
c.err = verr;
c.ret = 1;
goto bnum_compare_done;
}
c.n = bit_op_dec(num.width);
c.v = bit_op_dec(val.width);
nerr = num.sig_bit ? (num.value[c.n.node] & c.n.bit) : 0;
verr = val.sig_bit ? (val.value[c.v.node] & c.v.bit) : 0;
if ( nerr != 0 ) {
if ( verr == 0 ) {
c.ret = -1;
goto bnum_compare_done;
}
}
else if ( verr != 0 ) {
c.ret = 1;
goto bnum_compare_done;
}
for ( ; c.n.b > c.v.b; c.n = bit_op_dec(c.n) ) {
if ( num.value[c.n.node] & c.n.bit ) {
c.ret = 1;
goto bnum_compare_done;
}
}
for ( ; c.v.b > c.n.b; c.v = bit_op_dec(c.v) ) {
if ( val.value[c.v.node] & c.v.bit ) {
c.ret = -1;
goto bnum_compare_done;
}
}
for ( ; c.n.b || c.n.bit == 1; c.n = bit_op_dec(c.n), c.v = bit_op_dec(c.v) ) {
c.ret = -(val.value[c.v.node] & c.v.bit);
if ( num.value[c.n.node] & c.n.bit ) {
if ( c.ret == 0 ) {
c.ret = 1;
goto bnum_compare_done;
}
}
else if ( c.ret ) {
c.ret = -1;
goto bnum_compare_done;
}
}
bnum_compare_done:
if ( c.err != 0 ) {
puts("c.err");
(void)printerr(c.err);
puts("nerr");
(void)printerr(nerr);
puts("verr");
(void)printerr(verr);
}
return c;
}
bnum_cmp_t bnum_is_nil( bnum_t const num ) {
bnum_cmp_t c = {0};
bit_t e = bit_op_dec(num.width);
c.err = bnum_mem_chk(num);
c.n = num.width;
if ( c.err != 0 ) {
puts("c.err");
(void)printerr(c.err);
return c;
}
while ( c.n.b ) {
c.n = bit_op_dec(c.n);
if ( num.value[c.n.node] & c.n.bit ) {
if ( num.sig_bit )
c.ret = (num.value[e.node] & e.bit) ? -1 : 1;
else
c.ret = 1;
break;
}
}
return c;
}
_Bool bnum_op_nil( bnum_t const num ) {
return ((bnum_is_nil( num )).ret == 0);
}
_Bool bnum_op_eql( bnum_t const num, bnum_t const val ) {
return ( (bnum_compare(num,val)).ret == 0 );
}
_Bool bnum_op_neq( bnum_t const num, bnum_t const val ) {
return ( (bnum_compare(num,val)).ret != 0 );
}
_Bool bnum_op_gth( bnum_t const num, bnum_t const val ) {
return ( (bnum_compare(num,val)).ret > 0 );
}
_Bool bnum_op_gte( bnum_t const num, bnum_t const val ) {
return ( (bnum_compare(num,val)).ret >= 0 );
}
_Bool bnum_op_lth( bnum_t const num, bnum_t const val ) {
return ( (bnum_compare(num,val)).ret < 0 );
}
_Bool bnum_op_lte( bnum_t const num, bnum_t const val ) {
return ( (bnum_compare(num,val)).ret <= 0 );
}