Thread: Binary division of vector integer completed

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

    Binary division of vector integer completed

    Created this thread with this title specifically so people searching for binary division for this sort of thing will have something to reference, if you spot any problems however please let me know.

    The article that helped me finally achieve it:
    Wikipedia - Binary Division

    A copy paste of my dedicated file for division:
    Code:
    #include "op.h"
    int bnum_duvude( bnum_t num, bnum_t const val, bnum_t quo ) {
    	int ret;
    	bnum_t rem;
    	di width;
    	bit_t n, v;
    	ui overflow;
    	--overflow;
    	PRINT_IF_TRUE( num.sig_bit, return EINVAL; )
    	PRINT_IF_TRUE( val.sig_bit, return EINVAL; )
    	PRINT_IF_TRUE( quo.sig_bit, return EINVAL; )
    	PRINT_IF_TRUE( (ret = bnum_mem_chk(num)) != 0, return ret; )
    	PRINT_IF_TRUE( (ret = bnum_mem_chk(val)) != 0, return ret; )
    	PRINT_IF_TRUE( (ret = bnum_mem_chk(quo)) != 0, return ret; )
    	rem = num;
    	width = 0;
    	overflow = -1;
    	quo.sig_bit = 0;
    	ret = bnum_op_min(quo);
    	quo.sig_bit = num.sig_bit;
    	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;
    	}
    	/* num is made the remainder by the use of rem */
    	rem.start = rem.width;
    	rem.width.b = rem.start.b = 0;
    	/* The width helps clamp an inifinite division */
    	while ( rem.width.b < num.width.b &&
    		(ret = bnum_op_gte( num, val )) == 1 )
    	{
    		rem.start = bit_op_dec(rem.start);
    		rem.start.b = 0;
    		rem.width.b++;
    		PRINT_IF_TRUE( (ret = bnum_op_gte(rem,val)) > 1, return ret; )
    		if ( ret == 1 )
    		{
    			PRINT_IF_TRUE( (ret = bnum_op_sub(rem,val)) != 0, return ret; )
    			quo.value[rem.start.node] |= rem.start.bit;
    		}
    	}
    	PRINT_IF_TRUE( ret > 1, return ret; )
    	return bnum_op_shl_z(quo,width);
    }
    int bnum_divide( bnum_t num, bnum_t const val, bnum_t quo ) {
    	int ret;
    	bnum_t cpy;
    	if ( val.sig_bit ) {
    		PRINT_IF_TRUE( (ret = bnum_op_nil(val)) > 1 || ret < -1, return ret; )
    		if ( ret < 0 ) {
    			PRINT_IF_TRUE( (ret = bnum_mem_dup( &cpy, val )) != 0, return ret; )
    			PRINT_IF_TRUE( (ret = bnum_op_neg(cpy)) != 0, {} )
    			if ( ret == 0 ) {
    				cpy.sig_bit = 0;
    				PRINT_IF_TRUE( (ret = bnum_divide( num, cpy, quo )) != 0, {} )
    			}
    			bnum_mem_dec( &cpy, cpy.width.b );
    			return ret;
    		}
    		cpy = val;
    		cpy.sig_bit = 0;
    		return bnum_divide( num, cpy, quo );
    	}
    	if ( num.sig_bit ) {
    		PRINT_IF_TRUE( (ret = bnum_mem_chk(quo)) != 0, return ret; )
    		PRINT_IF_TRUE( (ret = bnum_op_nil(val)) > 1 || ret < -1, return ret; )
    		if ( ret < 0 ) {
    			PRINT_IF_TRUE( (ret = bnum_op_neg(num)) != 0, return ret; )
    			num.sig_bit = 0;
    			quo.sig_bit = 0;
    			PRINT_IF_TRUE( (ret = bnum_duvude( num, val, quo )) != 0, {} )
    			num.sig_bit = 1;
    			quo.sig_bit = 1;
    			(void)bnum_op_neg( num );
    			(void)bnum_op_neg( quo );
    			return ret;
    		}
    		num.sig_bit = 0;
    		quo.sig_bit = 0;
    		PRINT_IF_TRUE( (ret = bnum_duvude( num, val, quo )) != 0, {} )
    		num.sig_bit = 1;
    		quo.sig_bit = 1;
    		return ret;
    	}
    	return bnum_duvude( num, val, quo );
    }
    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;
    }

  2. #2
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    Code:
    PRINT_IF_TRUE...
    I'd like to see what you are doing there
    Fact - Beethoven wrote his first symphony in C

  3. #3
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    At work atm but it was something to this effect
    Code:
    if ( EXPR ) {
     printf("F:L Error: %s", TOSTR(EXPR) )
    do { ACT } while (0);
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help Integer division by zero
    By Red Man in forum C Programming
    Replies: 2
    Last Post: 04-10-2016, 12:30 PM
  2. Replies: 12
    Last Post: 01-13-2014, 06:32 PM
  3. Parsing an Integer with modulus and division
    By HoldenR in forum C Programming
    Replies: 6
    Last Post: 10-24-2012, 12:24 PM
  4. Replies: 5
    Last Post: 10-14-2009, 05:47 AM
  5. overloading the division operator with Integer Class
    By silk.odyssey in forum C++ Programming
    Replies: 3
    Last Post: 05-17-2004, 06:59 PM

Tags for this Thread