-
1st bit being missed
I'm not seeing where I went wrong on this so I'm hoping someone here can see it instead.
Output of the results (r/t) with the values starting off with:
Code:
r = 0b01100001010111111101101110110101, num = 0b10111100111001000010100001001001
t = 0b01100001010111111101101110110100, val = 0b01010001100110110101000000001101
Function that gives t it's result
Code:
int bnum_op_mul( bnum_t num, bnum_t const val ) {
int ret;
size_t width;
bool carry;
bit_t n, v, e, c;
bnum_t cpy;
PRINT_IF_TRUE( (ret = bnum_mem_chk( val )) != 0, return ret; )
PRINT_IF_TRUE( (ret = bnum_mem_dup( &cpy, num )) != 0, return ret; )
num.sig_bit = 0;
(void)bnum_op_min( num );
num.sig_bit = cpy.sig_bit;
e = bit_op_dec(num.width);
e.bit = num.sig_bit ? (num.value[e.node] & e.bit) : 0;
for ( v = val.start; v.b < val.width.b; v = bit_op_inc(v) ) {
if ( val.value[v.node] & v.bit ) {
carry = 0;
#if 0
PRINT_IF_TRUE( (ret = bnum_op_add( num, cpy )) != 0, return ret; )
#else
for
(
n = num.start, c = cpy.start;
c.b < cpy.width.b;
n = bit_op_inc(n), c = bit_op_inc(c)
)
{
if ( carry ) {
if ( num.value[n.node] & n.bit )
num.value[n.node] ^= n.bit;
else {
num.value[n.node] |= n.bit;
carry = 0;
}
}
if ( cpy.value[c.node] & c.bit ) {
if ( num.value[n.node] & n.bit ) {
num.value[n.node] ^= n.bit;
carry = 1;
}
else
num.value[n.node] |= n.bit;
}
}
if ( carry ) {
for ( ; n.b < num.width.b; n = bit_op_inc(n) ) {
if ( num.value[n.node] & n.bit )
num.value[n.node] ^= n.bit;
else {
num.value[n.node] |= n.bit;
carry = 0;
break;
}
}
}
#endif
}
num.width = cpy.width = bit_op_dec( cpy.width );
num.start = bit_op_inc( num.start );
num.start.b = 0;
}
(void)bnum_mem_dec( &cpy, cpy.width.b );
return bnum_clamp_inc( num, e.bit );
}
Bonus question, can anyone tell me why this function would have a different output than the above despite using the exact same logic for it's loop?
Code:
int bnum_op_add( bnum_t num, bnum_t const val ) {
int ret;
size_t width;
ub carry;
bit_t n, v, e;
PRINT_IF_TRUE( (ret = bnum_mem_chk( num )) != 0, return ret; )
PRINT_IF_TRUE( (ret = bnum_mem_chk( val )) != 0, return ret; )
carry = 0;
width = (num.width.b < val.width.b) ? num.width.b : val.width.b;
e = bit_op_dec( num.width );
e.bit = num.sig_bit ? (num.value[e.node] & e.bit) : 0;
for
(
n = num.start, v = val.start;
n.b < width;
n = bit_op_inc(n), v = bit_op_inc(v)
)
{
if ( carry ) {
if ( num.value[n.node] & n.bit )
num.value[n.node] ^= n.bit;
else {
num.value[n.node] |= n.bit;
carry = 0;
}
}
if ( val.value[v.node] & v.bit ) {
if ( num.value[n.node] & n.bit ) {
num.value[n.node] ^= n.bit;
carry = 1;
}
else
num.value[n.node] |= n.bit;
}
}
if ( carry ) {
for ( ; n.b < num.width.b; n = bit_op_inc(n) ) {
if ( num.value[n.node] & n.bit )
num.value[n.node] ^= n.bit;
else {
num.value[n.node] |= n.bit;
carry = 0;
break;
}
}
}
ret = bnum_clamp_inc( num, e.bit );
return ret;
}
-
Not quite sure how I managed it but I finally got that final bit, had corrected some clamping while I was at it, native overflow is detected and matched in behaviour for the sake of the tests, unfortunately my multiplication function takes around 11 cycles, most expensive so far, will have to refine that later but for now it will do.
Now I gotta fix my division function to remove the infinite loop, had a simple num >= val style loop but that fell hard, just stuck a check on seg(ment).width.b < num.width.b and that seems to work as a clamp, pity the result was still incorrect :(
Anyways time for some sleep