Thread: Bignum math: right shift

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

    Bignum math: right shift

    Thought that maybe my FPN math for double's with large exponents was giving wrong result because of insufficient integer size so I decided to write a all in one bignum math file and then try with that instead, either way I would need to for the compiler I'm writing.
    I got the left shift working just fine, I then did a copy & paste
    and flipped the direction of logic, unfortunately for some reason it's not working and I can't spot the problem myself, hoping someone here can.
    Code:
    Code:
    int shr__bi( bint_t *num, bint_t *val ) {
    	int ret = bint_validate2( num, val );
    	bint_t tmp = {0};
    	bibit_t n, v, e;
    	if ( ret != EXIT_SUCCESS ) return ret;
    	ret = bitemp( &tmp, &(num->stop.b), 1 );
    	if ( ret != EXIT_SUCCESS ) return ret;
    	if ( gte__bi( val, &tmp ) ) {
    		memset( num->zero.seg, 0, num->size );
    		return EXIT_SUCCESS;
    	}
    	else if ( !(*(val->zero.seg)) ) return EXIT_SUCCESS;
    	v = add_bibit( num->zero, *(val->zero.seg) );
    	n = num->zero;
    	e = dec_bibit(num->stop);
    	printf("e.b = %lu, v.b = %lu, n.b = %lu\n", e.b, v.b, n.b );
    	printf("e.bit = %016lX, v.bit = %016lu, n.bit = %016lu\n",
    		e.bit, v.bit, n.bit );
    	printf("num %016lX\n", *(num->zero.seg) );
    	while ( v.b < e.b ) {
    		n = inc_bibit(n);
    		v = inc_bibit(v);
    		if ( *(v.seg) & v.bit )
    			*(n.seg) |= n.bit;
    		else if ( *(n.seg) & n.bit )
    			*(n.seg) ^= n.bit;
    	}
    	printf("num %016lX\n", *(num->zero.seg) );
    	while ( n.bit << 1 ) {
    		n = inc_bibit(n);
    		if ( *(n.seg) & n.bit )
    			*(n.seg) ^= n.bit;
    	}
    	printf("num %016lX\n", *(num->zero.seg) );
    	if ( n.i < e.i ) {
    		n.i = e.i - n.i;
    		memset( ++(n.seg), 0, n.i * sizeof(biseg_t) );
    	}
    	return EXIT_SUCCESS;
    }
    Output:
    Code:
    gcc -Wall -o "bimath" "bimath.c" && "./bimath"
    _num = 0000000000000000, num = 0000000000000000, op = '=='
    _num = 0000000000000001, num = 0000000000000001, op = '!='
    _num = 0000000000000001, num = 0000000000000001, op = '>'
    _num = 0000000000000001, num = 0000000000000001, op = '>='
    _num = 0000000000000000, num = 0000000000000000, op = '<'
    _num = 0000000000000000, num = 0000000000000000, op = '<='
    _num = 0000000000000100, num = 0000000000000100, op = '<<'
    e.b = 63, v.b = 2, n.b = 0
    e.bit = 8000000000000000, v.bit = 0000000000000004, n.bit = 0000000000000001
    num 0000000000000040
    num 0000000000000000
    num 0000000000000000
    _num = 0000000000000000, num = 0000000000000010, op = '>>'
    _num = 0000000000000042, num = 0000000000000042, op = '+'
    Compilation finished successfully.
    Edit: Where _num is mentioned num is correct, _num is result of my functions
    Last edited by awsdert; 11-21-2019 at 04:44 AM.

  2. #2
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Turned out the problem was with add_bibit(), I forgot to filter out the scenario where bits % sizeof(biseg_t) AND bits < bitsof(biseg_t) were true.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 11
    Last Post: 05-19-2013, 04:16 PM
  2. logical shift and arithmetic shift.(bit shifting in C )
    By A34Chris in forum C Programming
    Replies: 20
    Last Post: 09-03-2012, 11:22 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