Thread: Bignum math: comparison

  1. #1
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733

    Bignum math: comparison

    I have a bug in my comparison code but I'm struggling to spot it, I'm hoping that someone here can:
    Code:
    int mcc__int_op_cmp( mcc_int_t const * const num, mcc_int_t const * const val ) {
    	mcc_bit_t n = {0}, v = {0};
    	mcc_int_seg_t nb = 0, vb = 0;
    	if ( num && num->zero.seg ) {
    		n = dec_for_bit(num->stop, num->zero);
    		nb = n.b - num->zero.b;
    	}
    	if ( val && val->zero.seg ) {
    		v = dec_for_bit(val->stop, val->zero);
    		vb = v.b - val->zero.b;
    	}
    	if ( !(n.bit) ) return v.bit ? -!!(*(v.seg) & v.bit) : 0;
    	if ( !(v.bit) ) return n.bit ? !!(*(n.seg) & n.bit) : 0;
    	if ( nb != vb ) return (nb > vb) ? 1 : -1;
    	while ( nb ) {
    		if ( nb ) {
    			n = dec_for_bit( n, num->zero );
    			nb = n.b - num->zero.b;
    		}
    		if ( vb ) {
    			v = dec_for_bit( v, val->zero );
    			vb = v.b - val->zero.b;
    		}
    		if ( nb != vb ) return ( nb > vb ) ? 1 : -1;
    	}
    	if ( !num || !val ) return nb ? 1 : -1;
    	return (!(*(n.seg) & n.bit) == !(*(v.seg) & v.bit));
    }
    #define mcc__int_is_nil( num ) ((mcc__int_op_cmp( num, NULL ) != 0))
    #define mcc__int_is_eql( num, val ) (mcc__int_op_cmp( num, val ) == 0)
    #define mcc__int_is_neq( num, val ) (mcc__int_op_cmp( num, val ) != 0)
    #define mcc__int_is_gth( num, val ) (mcc__int_op_cmp( num, val ) >  0)
    #define mcc__int_is_gte( num, val ) (mcc__int_op_cmp( num, val ) >= 0)
    #define mcc__int_is_lth( num, val ) (mcc__int_op_cmp( num, val ) <  0)
    #define mcc__int_is_lte( num, val ) (mcc__int_op_cmp( num, val ) <= 0)
    This is my output using all the bignum functions I have:
    Code:
    gcc -Wall -o "bimath" "bimath.c" && "./bimath"
    _num = 00000001, num = 00000000, b4 = 00000001, val = 00000000, _rem = 00000001, rem = 00000001 op = '!'
    _num = 00000000, num = 00000000, b4 = 00000101, val = 00000001, _rem = 00000101, rem = 00000101 op = '=='
    _num = 00000001, num = 00000001, b4 = 00000203, val = 00000002, _rem = 00000203, rem = 00000203 op = '!='
    _num = 00000001, num = 00000001, b4 = 00000303, val = 00000003, _rem = 00000303, rem = 00000303 op = '>'
    _num = 00000001, num = 00000001, b4 = 00000405, val = 00000004, _rem = 00000405, rem = 00000405 op = '>='
    _num = 00000000, num = 00000000, b4 = 00000505, val = 00000005, _rem = 00000505, rem = 00000505 op = '<'
    _num = 00000000, num = 00000000, b4 = 00000607, val = 00000006, _rem = 00000607, rem = 00000607 op = '<='
    _num = 00038380, num = 00038380, b4 = 00000707, val = 00000007, _rem = 00000707, rem = 00000707 op = '<<'
    _num = 00000008, num = 00000008, b4 = 00000809, val = 00000008, _rem = 00000809, rem = 00000809 op = '>>'
    _num = 00000909, num = 00000909, b4 = 00000909, val = 00000009, _rem = 00000909, rem = 00000909 op = '|'
    _num = 0000000A, num = 0000000A, b4 = 00000A0B, val = 0000000A, _rem = 00000A0B, rem = 00000A0B op = '&'
    _num = 00000B00, num = 00000B00, b4 = 00000B0B, val = 0000000B, _rem = 00000B0B, rem = 00000B0B op = '^'
    _num = 00000C19, num = 00000C19, b4 = 00000C0D, val = 0000000C, _rem = 00000C0D, rem = 00000C0D op = '+'
    _num = 0000A9A9, num = 0000A9A9, b4 = 00000D0D, val = 0000000D, _rem = 00000D0D, rem = 00000D0D op = '*'
    _num = 00000E01, num = 00000E01, b4 = 00000E0F, val = 0000000E, _rem = 00000E0F, rem = 00000E0F op = '-'
    _num = 00000101, num = 00000101, b4 = 00000F0F, val = 0000000F, _rem = 00000000, rem = 00000000 op = '/'
    _num = 00001011, num = 00001011, b4 = 00001011, val = 00000010, _rem = 00001011, rem = 00001011 op = '%'
    Compilation finished successfully.

  2. #2
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Whoops, noticed I used the wrong comparison on the is_nil() one, however that wasn't the bug I was getting at, had to re-order the comparisons so that the bug showed since I added in that is_nil() after I found the bug and hadn't tested the fix yet, here's the output with the bug showing:
    Code:
    gcc -Wall -o "bimath" "bimath.c" && "./bimath"
    _num = 00000001, num = 00000000, b4 = 00000001, val = 00000000, _rem = 00000001, rem = 00000001 op = '=='
    _num = 00000001, num = 00000001, b4 = 00000101, val = 00000001, _rem = 00000101, rem = 00000101 op = '!='
    _num = 00000000, num = 00000000, b4 = 00000203, val = 00000002, _rem = 00000203, rem = 00000203 op = '!'
    _num = 00000001, num = 00000001, b4 = 00000303, val = 00000003, _rem = 00000303, rem = 00000303 op = '>'
    _num = 00000001, num = 00000001, b4 = 00000405, val = 00000004, _rem = 00000405, rem = 00000405 op = '>='
    _num = 00000000, num = 00000000, b4 = 00000505, val = 00000005, _rem = 00000505, rem = 00000505 op = '<'
    _num = 00000000, num = 00000000, b4 = 00000607, val = 00000006, _rem = 00000607, rem = 00000607 op = '<='
    _num = 00038380, num = 00038380, b4 = 00000707, val = 00000007, _rem = 00000707, rem = 00000707 op = '<<'
    _num = 00000008, num = 00000008, b4 = 00000809, val = 00000008, _rem = 00000809, rem = 00000809 op = '>>'
    _num = 00000909, num = 00000909, b4 = 00000909, val = 00000009, _rem = 00000909, rem = 00000909 op = '|'
    _num = 0000000A, num = 0000000A, b4 = 00000A0B, val = 0000000A, _rem = 00000A0B, rem = 00000A0B op = '&'
    _num = 00000B00, num = 00000B00, b4 = 00000B0B, val = 0000000B, _rem = 00000B0B, rem = 00000B0B op = '^'
    _num = 00000C19, num = 00000C19, b4 = 00000C0D, val = 0000000C, _rem = 00000C0D, rem = 00000C0D op = '+'
    _num = 0000A9A9, num = 0000A9A9, b4 = 00000D0D, val = 0000000D, _rem = 00000D0D, rem = 00000D0D op = '*'
    _num = 00000E01, num = 00000E01, b4 = 00000E0F, val = 0000000E, _rem = 00000E0F, rem = 00000E0F op = '-'
    _num = 00000101, num = 00000101, b4 = 00000F0F, val = 0000000F, _rem = 00000000, rem = 00000000 op = '/'
    _num = 00001011, num = 00001011, b4 = 00001011, val = 00000010, _rem = 00001011, rem = 00001011 op = '%'
    Compilation finished successfully.

  3. #3
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    I finally fixed it, I changed the end of the function to this:
    Code:
    	nb = (*(n.seg) & n.bit) ? 1 : 0;
    	vb = (*(v.seg) & v.bit) ? 1 : 0;
    	if ( nb != vb )	return (nb > vb) ? 1 : -1;
    	return 0;

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Bignum math: division
    By awsdert in forum C Programming
    Replies: 1
    Last Post: 11-21-2019, 06:34 PM
  2. Bignum math: right shift
    By awsdert in forum C Programming
    Replies: 1
    Last Post: 11-21-2019, 05:13 AM
  3. Implementing divison for bignum ?
    By jack_carver in forum C Programming
    Replies: 2
    Last Post: 02-24-2010, 11:33 PM
  4. Help in implementing BIGNUM
    By jack_carver in forum C++ Programming
    Replies: 15
    Last Post: 10-09-2009, 08:22 PM
  5. BigNum Quick Question?
    By gqchynaboy in forum C++ Programming
    Replies: 12
    Last Post: 09-10-2003, 09:06 PM

Tags for this Thread