Thread: Struggling to see what I did wrong

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

    Struggling to see what I did wrong

    Was doing some checking on my bnum_t functions/math and found a lot of mistakes, I've managed to fix them so far up to this point but now I just can't spot what I did wrong, here's the relevant segment of output:
    Code:
    operation(1726956429,'<',5) call 4
    rstarted 1198, rstopped 1199, nstarted 1199, nstopped 1228
    num << val -571969120, 1709982365
    Numerical argument out of domain
    ../makefile:15: recipe for target 'run' failed
    make: *** [run] Error 1
    Compilation failed.
    And the function I'm testing:
    Code:
    int bnum_op_shl( bnum_t num, bnum_t const val ) {
    	int ret = bnum_mem_chk( num );
    	size_t mov, bit, i;
    	bnum_t max = {bnum_init};
    	bit_t n, v;
    	if ( ret != 0 ) return ret;
    	ret = bnum_mem_chk( val );
    	if ( ret != 0 ) return ret;
    	if ( bnum_op_nil( val ) )
    		return 0;
    	max = int2bnum( &mov, sizeof(size_t), 0 );
    	mov = num.width;
    	if ( bnum_op_gte( val, max ) )
    		return bnum_op_muv( num, 0 );
    	/* Here onwards should be the only faulty code */
    	mov = B_WIDTH;
    	n = v = num.stop;
    	while ( bnum_op_gth( val, max ) ) {
    		v.byte--;
    		v.b -= B_WIDTH;
    		mov += B_WIDTH;
    	}
    	--mov;
    	while ( bnum_op_lth( val, max ) ) {
    		v = bit_op_dec(v);
    		--mov;
    	}
    	while ( v.b ) {
    		n = bit_op_dec(n);
    		v = bit_op_dec(v);
    		if ( val.value[v.byte] & v.bit )
    			num.value[n.byte] |= n.bit;
    		else if ( num.value[n.bit] & n.bit )
    			num.value[n.byte] ^= n.bit;
    	}
    	while ( n.b ) {
    		n = bit_op_dec(n);
    		if ( num.value[n.bit] & n.bit )
    			num.value[n.byte] ^= n.bit;
    	}
    	return 0;
    }
    And if you're curious the full output:
    Code:
    make run (in directory: /media/lee/ZXUIJI_1TB/github/code/bnum)
    gcc -o ../code.elf ../print.o ../predef.o ../chk.o ../add.o ../code.o ../open.o ../mem_inc.o ../shut.o ../init_and_term.o ../get.o ../bnum/bit.o ../bnum/cmp.o ../bnum/math.o ../bnum/div.o
    ./../code.elf
    
    Testing Integer Comparisons...
    comparison( 846930886, 'n', 1804289383 ) call 0
    rstarted 570; rstopped 570, nstarted 570, nstopped 571
    !num 0, 0
    comparison( 1714636915, '=', 1681692777 ) call 1
    rstarted 573; rstopped 574, nstarted 574, nstopped 575
    num == val 0, 0
    comparison( 424238335, '!', 1957747793 ) call 2
    rstarted 576; rstopped 577, nstarted 577, nstopped 578
    num != val 1, 1
    comparison( 1649760492, '>', 719885386 ) call 3
    rstarted 579; rstopped 579, nstarted 580, nstopped 580
    num >= val 1, 1
    comparison( 1189641421, 'g', 596516649 ) call 4
    rstarted 582; rstopped 582, nstarted 582, nstopped 583
    num > val 1, 1
    comparison( 1350490027, '<', 1025202362 ) call 5
    rstarted 584; rstopped 585, nstarted 585, nstopped 586
    num <= val 0, 0
    comparison( 1102520059, 'l', 783368690 ) call 6
    rstarted 587; rstopped 587, nstarted 588, nstopped 588
    num < val 0, 0
    
    Testing Single Integer Operations...
    operation1('~',2044897763) call 0
    rstarted 590, rstopped 590, nstarted 590, nstopped 591
    ~num -2044897764, -2044897764
    operation1('+',1967513926) call 1
    rstarted 593, rstopped 593, nstarted 593, nstopped 594
    ++num 1967513927, 1967513927
    operation1('-',1365180540) call 2
    rstarted 595, rstopped 596, nstarted 596, nstopped 597
    --num 1365180539, 1365180539
    
    Testing Double Integer Operations...
    operation2(304089172,'&',1540383426) call 0
    rstarted 598, rstopped 599, nstarted 599, nstopped 600
    num & val 301989952, 301989952
    operation2(35005211,'|',1303455736) call 1
    rstarted 602, rstopped 602, nstarted 602, nstopped 604
    num | val 1337403387, 1337403387
    operation2(294702567,'^',521595368) call 2
    rstarted 605, rstopped 606, nstarted 606, nstopped 607
    num ^ val 243672079, 243672079
    operation2(336465782,'<',5) call 3
    rstarted 605, rstopped 606, nstarted 606, nstopped 607
    num << val 336465782, 336465782
    Operation not permitted
    ../makefile:15: recipe for target 'run' failed
    make: *** [run] Error 1
    Compilation failed.
    Edit: Changed a few printf() calls to make my output a bit more readable
    Last edited by awsdert; 07-05-2019 at 04:43 AM.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    37,312
    > operation(1726956429,'<',5) call 4
    > rstarted 1198, rstopped 1199, nstarted 1199, nstopped 1228
    > num << val -571969120, 1709982365
    Why does less-than appear as left-shift?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    462
    Was using a switch statement, compiler complained when I tried multi-byte characters so I separated the operation testing into separate functions, that character just made it easy to quickly identify what operation I was testing in that function, used a loop with dedicate arrays to get consistent handling

    Edit: Have to go to work, intend to check back tomorrow
    Last edited by awsdert; 07-05-2019 at 04:46 AM.

  4. #4
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    462
    Was looking at my code while waiting to start work and noticed I used n.bit instead of n.byte to access an array member, this post is just a reminder for me to correct that, might fix the result in turn

  5. #5
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    462
    Fixed the wrong variable usage but the problem remains the same, just different output
    Code:
    int bnum_op_shl( bnum_t num, bnum_t const val ) {
    	int ret = bnum_mem_chk( num );
    	size_t mov, bit, i;
    	bnum_t max = {bnum_init};
    	bit_t n, v, e;
    	if ( ret != 0 ) return ret;
    	ret = bnum_mem_chk( val );
    	if ( ret != 0 ) return ret;
    	mov = num.width;
    	max = int2bnum( &mov, sizeof(size_t), 0 );
    	if ( bnum_op_gte( val, max ) )
    		return num.sig_bit ? bnum_op_mdv( num, 0 ) : bnum_op_muv( num, 0 );
    	(void)bnum_op_cpy( max, val );
    	if ( !mov ) return 0;
    	n = v = num.stop;
    	e = bit_op_dec(num.stop);
    	e.bit = num.sig_bit ? (num.value[e.byte] & e.bit) : 0;
    	while ( mov >= B_WIDTH ) {
    		v.byte--;
    		v.b -= B_WIDTH;
    		mov -= B_WIDTH;
    	}
    	while ( --mov )
    		v = bit_op_dec(v);
    	while ( v.b ) {
    		n = bit_op_dec(n);
    		v = bit_op_dec(v);
    		if ( val.value[v.byte] & v.bit )
    			num.value[n.byte] |= n.bit;
    		else if ( num.value[n.byte] & n.bit )
    			num.value[n.byte] ^= n.bit;
    	}
    	while ( n.b ) {
    		n = bit_op_dec(n);
    		if ( num.value[n.byte] & n.bit )
    			num.value[n.byte] ^= n.bit;
    	}
    	if ( num.sig_bit )
    		num.value[e.byte] |= e.bit;
    	return 0;
    }
    produced
    Code:
    ...
    operation2(1726956429,'<',5) call 3
    rstarted 819, rstopped 820, nstarted 820, nstopped 826
    num << val -571969120, 80
    r = 0b11011101111010000111000110100000
    t = 0b00000000000000000000000001010000
    Numerical argument out of domain
    ../makefile:15: recipe for target 'run' failed
    make: *** [run] Error 1
    Compilation failed.

  6. #6
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    462
    Fixed it, didn't realise I had been extracting bits from wrong variable during the loop stage, here's the changed part:
    Code:
    int bnum_op_shl( bnum_t num, bnum_t const val ) {
    ...
    	while ( mov-- )
    		v = bit_op_dec(v);
    	while ( v.b ) {
    		n = bit_op_dec(n);
    		v = bit_op_dec(v);
    		if ( num.value[v.byte] & v.bit )
    			num.value[n.byte] |= n.bit;
    		else if ( num.value[n.byte] & n.bit )
    			num.value[n.byte] ^= n.bit;
    	}
    ...
    Took 5 cycles for an 8 byte integer so not horrendous like when my first attempt (29 cycles), that call to bnum_op_cpy() made a huge difference cycle wise, gonna attempt to reduce that further by doing an #ifdef for optimizing via speed or size

  7. #7
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    462
    Well I did some refinements (with the original functions converted to macros using the below), left shift is working as expected and right shift is ALMOST working as expected but some wierd error occured in the middle as you can see via the binary at the bottom ("r" uses int >> int & "t" uses bnum_t >> bnum_t).
    Code:
    Code:
    int bnum_op_shl_z( bnum_t num, size_t val ) {
    	int ret = bnum_mem_chk( num );
    	bit_t n, v, e;
    	if ( ret != 0 ) return ret;
    	if ( !val ) return 0;
    	else if ( val >= num.width )
    		return bnum_op_min( num );
    	n = v = num.stop;
    	e = bit_op_dec(n);
    	e.bit = num.sig_bit ? (num.value[e.byte] & e.bit) : 0;
    	while ( val >= B_WIDTH ) {
    		v.byte--;
    		v.b -= B_WIDTH;
    		val -= B_WIDTH;
    	}
    	while ( val-- )
    		v = bit_op_dec(v);
    	while ( v.b ) {
    		n = bit_op_dec(n);
    		v = bit_op_dec(v);
    		if ( num.value[v.byte] & v.bit )
    			num.value[n.byte] |= n.bit;
    		else if ( num.value[n.byte] & n.bit )
    			num.value[n.byte] ^= n.bit;
    	}
    	while ( n.b ) {
    		n = bit_op_dec(n);
    		if ( num.value[n.byte] & n.bit )
    			num.value[n.byte] ^= n.bit;
    	}
    	if ( num.sig_bit )
    		num.value[e.byte] |= e.bit;
    	return 0;
    }
    int bnum_op_shr_z( bnum_t num, size_t val ) {
    	int ret = bnum_mem_chk( num );
    	bit_t n, v, e;
    	if ( ret != 0 ) return ret;
    	if ( !val ) return 0;
    	else if ( val >= num.width )
    		return bnum_op_min( num );
    	n = v = num.init;
    	e = bit_op_dec(n);
    	e.bit = num.sig_bit ? (num.value[e.byte] & e.bit) : 0;
    	while ( val >= B_WIDTH ) {
    		v.byte++;
    		v.b += B_WIDTH;
    		val -= B_WIDTH;
    	}
    	while ( val-- )
    		v = bit_op_inc(v);
    	for ( ; v.b < num.width; n = bit_op_inc(n), v = bit_op_inc(v) ) {
    		if ( num.value[v.byte] & v.bit )
    			num.value[n.byte] |= n.bit;
    		else if ( num.value[n.byte] & n.bit )
    			num.value[n.byte] ^= n.bit;
    	}
    	for ( ; v.b < num.width; n = bit_op_inc(n) ) {
    		n = bit_op_dec(n);
    		if ( num.value[n.byte] & n.bit )
    			num.value[n.byte] ^= n.bit;
    	}
    	if ( num.sig_bit )
    		num.value[e.byte] |= e.bit;
    	return 0;
    }
    Output Segment:
    Code:
    ...
    operation2(-861021530,'<',5) call 4
    rstarted 512, rstopped 513, nstarted 513, nstopped 517
    num << val -1782885184, -1782885184
    operation2(-233665123,'>',5) call 5
    rstarted 518, rstopped 518, nstarted 519, nstopped 522
    num >> val -7302036, -141519764
    r = 0b11111111100100001001010001101100
    t = 0b11110111100100001001010001101100
    Numerical argument out of domain
    ../makefile:15: recipe for target 'run' failed
    make: *** [run] Error 1
    Compilation failed.

  8. #8
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    462
    Fixed it, had to change the type of val from size_t to ssize_t and add a check for which loop to finish off with:
    Code:
    int bnum_op_shl_z( bnum_t num, ssize_t val ) {
    	int ret = bnum_mem_chk( num );
    	bit_t n, v, e;
    	size_t mov = (val < 0 && val > -SSIZE_MAX) ? -val : val;
    	if ( ret != 0 ) return ret;
    	if ( !mov ) return 0;
    	else if ( mov >= num.width )
    		return bnum_op_min( num );
    	n = v = num.stop;
    	e = bit_op_dec(n);
    	e.bit = num.sig_bit ? (num.value[e.byte] & e.bit) : 0;
    	while ( mov >= B_WIDTH ) {
    		v.byte--;
    		v.b -= B_WIDTH;
    		val -= B_WIDTH;
    	}
    	while ( mov-- )
    		v = bit_op_dec(v);
    	while ( v.b ) {
    		n = bit_op_dec(n);
    		v = bit_op_dec(v);
    		if ( num.value[v.byte] & v.bit )
    			num.value[n.byte] |= n.bit;
    		else if ( num.value[n.byte] & n.bit )
    			num.value[n.byte] ^= n.bit;
    	}
    	if ( val < 0 ) {
    		while ( n.b ) {
    			n = bit_op_dec(n);
    			num.value[n.byte] |= n.bit;
    		}
    	}
    	else {
    		while ( n.b ) {
    			n = bit_op_dec(n);
    			if ( num.value[n.byte] & n.bit )
    				num.value[n.byte] ^= n.bit;
    		}
    	}
    	if ( num.sig_bit )
    		num.value[e.byte] |= e.bit;
    	return 0;
    }
    int bnum_op_shr_z( bnum_t num, ssize_t val ) {
    	int ret = bnum_mem_chk( num );
    	bit_t n, v, e;
    	size_t mov = (val < 0 && val > -SSIZE_MAX) ? -val : val;
    	if ( ret != 0 ) return ret;
    	if ( !mov ) return 0;
    	else if ( mov >= num.width )
    		return bnum_op_min( num );
    	n = v = num.init;
    	e = bit_op_dec(n);
    	e.bit = num.sig_bit ? (num.value[e.byte] & e.bit) : 0;
    	while ( val >= B_WIDTH ) {
    		v.byte++;
    		v.b += B_WIDTH;
    		val -= B_WIDTH;
    	}
    	while ( val-- )
    		v = bit_op_inc(v);
    	for ( ; v.b < num.width; n = bit_op_inc(n), v = bit_op_inc(v) ) {
    		if ( num.value[v.byte] & v.bit )
    			num.value[n.byte] |= n.bit;
    		else if ( num.value[n.byte] & n.bit )
    			num.value[n.byte] ^= n.bit;
    	}
    	if ( val < 0 ) {
    		for ( ; n.b < num.width; n = bit_op_inc(n) )
    				num.value[n.byte] |= n.bit;
    	}
    	else {
    		for ( ; n.b < num.width; n = bit_op_inc(n) ) {
    			if ( num.value[n.byte] & n.bit )
    				num.value[n.byte] ^= n.bit;
    		}
    	}
    	if ( num.sig_bit )
    		num.value[e.byte] |= e.bit;
    	return 0;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Struggling with a new lua project
    By awsdert in forum C Programming
    Replies: 6
    Last Post: 11-30-2018, 11:03 AM
  2. Struggling with VEX programing
    By sixtysix in forum C Programming
    Replies: 1
    Last Post: 05-16-2016, 04:16 AM
  3. Struggling With the Next Step.
    By Dobblaar in forum C Programming
    Replies: 8
    Last Post: 11-28-2013, 05:06 PM
  4. Need some help with this code. Struggling
    By NoobCoder85 in forum C++ Programming
    Replies: 2
    Last Post: 11-25-2013, 02:34 AM
  5. Struggling to understand C, and where I am going wrong.
    By DARK_STALKER in forum C Programming
    Replies: 1
    Last Post: 11-29-2012, 10:44 AM

Tags for this Thread