Thread: Drawing a blank, posting in case someone else has an idea

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

    Drawing a blank, posting in case someone else has an idea

    Currently trying to fix an integer to float function, does positive numbers just fine but chokes on negatives, seems to be just one off so was looking for the potential fix in the final part of the function. Gonna take a break and come back to it after some gaming, not expecting there to be many people interested in trying but should be easy enough for someone interested in a quick brain teaser of sorts.
    Code:
    make check.run
    ...
    Running suite(s): ALU
    ../tests/check_alu.c:551: test_alup_mov_neg2flt_fn() Before = -1, Expect -2.000000, Result -1.000000
    ../tests/check_alu.c:559: test_alup_mov_neg2flt_fn() &_RESULT: part = 0x7fffffffe084, bits = 32, upto = 32, from = 0, signed = 1, mdig = 24, _EXP.bits = 8, _MAN.bits = 23
    ../tests/check_alu.c:559: test_alup_mov_neg2flt_fn() &_RESULT = 1 +0000 01111111 000'0000'0000'0000'0000'0000
    ../tests/check_alu.c:560: test_alup_mov_neg2flt_fn() &_EXPECT: part = 0x7fffffffe080, bits = 32, upto = 32, from = 0, signed = 1, mdig = 24, _EXP.bits = 8, _MAN.bits = 23
    ../tests/check_alu.c:560: test_alup_mov_neg2flt_fn() &_EXPECT = 1 +0001 10000000 000'0000'0000'0000'0000'0000
    ../tests/check_alu.c:561: test_alup_mov_neg2flt_fn() &_BEFORE: part = 0x7fffffffe088, bits = 64, upto = 64, from = 0, signed = 1, mdig = 0, _EXP.bits = 0, _MAN.bits = 0
    ../tests/check_alu.c:561: test_alup_mov_neg2flt_fn() &_BEFORE = 1 111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111
    99%: Checks: 4312, Failures: 1, Errors: 0
    ...
    Compilation finished successfully.
    Code:
    int_t	alup_mov_int2flt( alup_t const * const _DST, alup_t const * const _SRC )
    {
    	alub_t s;
    	ssize_t exp, bias;
    	bool neg = alup_below0( _SRC ), is0;
    	
    	s = alup_final_bit_with_val( _SRC, !neg );
    	exp = s.bit - _SRC->from;
    	is0 = !(neg || exp || !!(*(s.ptr) & s.mask) != neg);
    	
    	if ( is0 )
    	{	
    		(void)alup_set( _DST, 0 );
    		return ENODATA;
    	}
    	
    	bias = alup_get_exponent_bias( _DST );
    	
    	if ( exp >= bias )
    	{	
    		(void)alup_set_inf( _DST, neg );
    		return ERANGE;
    	}
    	else
    	{
    		alup_t _MAN, _REF;
    		ssize_t upto = LOWEST( exp + 1, (ssize_t)(_DST->mdig) );
    		
    		alup_init_mantissa( _DST, _MAN );
    		alup_set( &_MAN, 0 );
    		
    		//alu_printf( "exp = %zd, upto = %zd", exp, upto );
    		
    		_REF = *_SRC;
    		_REF.bits = upto - 1;
    		_REF.from = IFTRUE( s.bit, s.bit - _REF.bits );
    		_MAN.from += ( _DST->mdig - upto );
    		
    		//alup_print( &_REF, 1, 1 );
    		
    		(void)alup_mov_int2int( &_MAN, &_REF );
    		
    		/* Round to nearest */
    		if ( _SRC->from < _REF.from )
    		{
    			s = alub( _REF.data, _REF.from - 1 );
    			
    			if ( *(s.ptr) & s.mask )
    				alup_inc( &_MAN );
    		}
    		
    		(void)alup_set_exponent( _DST, exp + bias );
    		alup_set_sign( _DST, neg );
    		
    		return 0;
    	}
    }

  2. #2
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    As it happens my previous code where the negative was temporarily converted to positive prior to analysis and movement was actually correct, seems the bug I encountered that led me to believe otherwise was simply misrepresenting the problem, anyways here's the code for the curious:
    Code:
    int_t	alup_mov_int2flt( alup_t const * const _DST, alup_t const * const _SRC )
    {
    	alub_t s;
    	ssize_t exp, bias;
    	bool neg = alup_below0( _SRC ), is0, val;
    	
    	if ( neg )
    	{
    		alup_neg( _SRC );
    	}
    	
    	s = alup_final_bit_with_val( _SRC, 1 );
    	val = !!(*(s.ptr) & s.mask);
    	exp = s.bit - _SRC->from;
    	is0 = !(neg || exp || val != neg);
    	
    	if ( is0 )
    	{	
    		if ( neg )
    		{
    			alup_neg( _SRC );
    		}
    		
    		(void)alup_set( _DST, 0 );
    		return ENODATA;
    	}
    	
    	bias = alup_get_exponent_bias( _DST );
    	
    	if ( exp >= bias )
    	{
    		if ( neg )
    		{
    			alup_neg( _SRC );
    		}
    		
    		(void)alup_set_inf( _DST, neg );
    		return ERANGE;
    	}
    	else
    	{
    		alup_t _MAN, _REF;
    		ssize_t upto = LOWEST( exp + 1, (ssize_t)(_DST->mdig) );
    		
    		alup_init_mantissa( _DST, _MAN );
    		alup_set( &_MAN, 0 );
    		
    		_REF = *_SRC;
    		_REF.bits = upto - 1;
    		_REF.from = IFTRUE( s.bit, s.bit - _REF.bits );
    		_MAN.from += ( _DST->mdig - upto );
    		
    		(void)alup_mov_int2int( &_MAN, &_REF );
    		
    		if ( neg )
    		{
    			alup_neg( _SRC );
    		}
    		
    		/* Round to nearest */
    		if ( _SRC->from < _REF.from )
    		{
    			s = alub( _REF.data, _REF.from - 1 );
    			
    			if ( *(s.ptr) & s.mask )
    				alup_inc( &_MAN );
    		}
    
    		(void)alup_set_exponent( _DST, exp + bias );
    		alup_set_sign( _DST, neg );
    		
    		return 0;
    	}
    }

  3. #3
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    I went back to the original bug where floating subtraction did not yield negative numbers in the appropriate cases, I tried applying my new knowledge of how negative numbers are represented to correct the original code (will have to do similar for addition later) but still got incorrect result/s, anyone have any ideas?
    Code:
    /** @brief Holds various values for bit position in a number
     * @param seg Index number of size_t sized data segments
     * @param bit Overall bit from 0 to alur.upto
     * @param pos Position of bit from 0 to bitsof(T)
     * @param ptr Segment that is bit is in
     * @param mask Mask needed to reference specific bit
    **/
    typedef struct alub {
    	uintmax_t seg, bit, pos, *ptr, mask;
    } alub_t;
    ...
    typedef struct alup
    {
    	/* Root pointer for the number (useful for sub math like addition in
    	 * multiplication) */
    	void *	data;
    	/* Position from data */
    	size_t	from, last, upto;
    	/* Total bits in the number */
    	size_t	bits;
    	/* 0 means an integer */
    	size_t	mdig;
    	/* Must be set for floating values, at least for now */
    	bool_t	sign;
    } alup_t;
    ...
    int_t alup__sub( alup_t const * const _NUM, alup_t const * const _VAL, void *_cpy, void *_tmp )
    {	
    	if ( alup_floating( _NUM ) || alup_floating( _VAL ) )
    	{
    		int_t ret;
    		alup_t _CPY, _TMP;
    		ssize_t cexp, texp;
    		size_t bits = HIGHEST( _NUM->bits, _VAL->bits );
    		bool_t truncated = false;
    		
    		alup_init_floating( _CPY, _cpy, bits );
    		alup_init_floating( _TMP, _tmp, bits );
    		
    		alup_mov( &_CPY, _NUM );
    		alup_mov( &_TMP, _VAL );
    		
    		cexp = alup_get_exponent( &_CPY );
    		texp = alup_get_exponent( &_TMP );
    		
    		if ( cexp || texp )
    		{
    			bool_t neg = alup_below0( &_CPY );
    			alub_t final;
    			alup_t _CMAN, _TMAN;
    			ssize_t bias = alup_get_exponent_bias( &_CPY ), exp;
    			
    			ret = alup_match_exponents( _CPY.data, _TMP.data, bits );
    			
    			truncated = (ret == ERANGE);
    			
    			exp = alup_get_exponent( &_CPY );
    			
    			alup_init_mantissa( &_CPY, _CMAN );
    			alup_init_mantissa( &_TMP, _TMAN );
    			
    			ret = alup__sub_int2int( &_CMAN, &_TMAN );
    			
    			if ( ret == EOVERFLOW )
    			{
    				neg = !neg;
    				alup_neg( &_CMAN );
    			}
    			
    			final = alup_final_bit( &_CMAN );
    			exp = _CMAN.upto - final.bit;
    			
    			alup_set_sign( &_CPY, neg );
    			
    			(void)alup_set_exponent( &_CPY, IFTRUE( exp, exp + bias ) );
    		}
    		
    		ret = alup_mov( _NUM, &_CPY );
    		
    		return IFTRUE( truncated || ret == ERANGE, ERANGE );
    	}
    	
    	return alup__sub_int2int( _NUM, _VAL );
    }
    Haven't yet looked up the convention for documenting structures &/or classes so forgive the inconsistent style that resulted from commenting haphazardly.

  4. #4
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    I'm guessing noone else had any ideas either... or just wasn't interested, I'm betting on the lata, eh I'll just come back to it 2mw

  5. #5
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Got back to it 2day instead, anyways I tried a couple of things then noticed I needed some variable from the exponent matching stage (forgot what it was and for what purpose by the time I combined the code into below function), now I can get passed the incremental and randomized tests but the absolute value tests currently fail (I suspect the other tests were purely coincidental), I'm drawing a blank on ideas right now so I'm just gonna dump the problem here and see if anyone was interested enough to give it a try (uploaded the changes to my alu project on github so you can look for details not mentioned here there). I'll do some gaming in meantime until I either get an idea or I find reasonable stop points to come check if anyone else had an idea (just in case someone thinks to ask what it is supposed to do, it is supposed to replicate the math at the binary level that computers do for floats, doubles & long double, just without the hard limits of 32bit, 64bit and 80bit)

    Output:
    Code:
    make check.run
    ...
    Running suite(s): ALU
    ../tests/check_alu.c:1359: test_alup__op4_floating_absolute_fn() exp_dig = 8, man_dig = 23, 1327753856.000000 - 1770012288.000000 = -442258432.000000, got 0.000000
    ../tests/check_alu.c:1372: test_alup__op4_floating_absolute_fn() &_EXPECT = 1 +0028 10011011 101'0010'1110'0010'1010'0000
    ../tests/check_alu.c:1373: test_alup__op4_floating_absolute_fn() &_RESULT = 0 +0000 00000000 000'0000'0000'0000'0000'0000
    99%: Checks: 4312, Failures: 1, Errors: 0
    ...
    Compilation finished successfully.
    Code:
    Code:
    typedef int_t (*alup__addsub_int2int)( alup_t const * const _NUM, alup_t const * const _VAL );
    
    /* Currently only alup__sub() uses this function (this comment does not exist in source code, the above line does however currently sit directly above this function),
    the reason is that it currently does not work on addition (and is the reason I suspect the other subtraction tests were coincidental), the do/while loop exists because
    I copy pasted code from 2 existing functions into this one then modified it to not have excess variables that could've just been shared, the change I wanted to make
    however is yet to be done because as mentioned I forgot what it was by the time I finished putting this function together */
    
    int_t alup_addsub
    (
    	alup_t const * const _NUM
    	, alup_t const * const _VAL
    	, void *_cpy
    	, void *_tmp
    	, alup__addsub_int2int addsub
    )
    {
    	if ( alup_floating( _NUM ) || alup_floating( _VAL ) )
    	{
    		int_t ret;
    		alup_t _CPY, _TMP;
    		ssize_t cexp, texp;
    		size_t bits = HIGHEST( _NUM->bits, _VAL->bits );
    		bool_t truncated = false;
    		
    		alup_init_floating( _CPY, _cpy, bits );
    		alup_init_floating( _TMP, _tmp, bits );
    		
    		(void)alup_mov( &_CPY, _NUM );
    		(void)alup_mov( &_TMP, _VAL );
    		
    		cexp = alup_get_exponent( &_CPY );
    		texp = alup_get_exponent( &_TMP );
    		
    		if ( cexp || texp )
    		{
    			bool_t neg = alup_below0( &_CPY );
    			alub_t final;
    			alup_t _CMAN, _TMAN;
    			size_t bias = alup_get_exponent_bias( &_CPY ), exp = 0;
    			
    			do
    			{
    				alup_t _DST = {0};
    				size_t diff = 0;
    					
    				if ( cexp > texp )
    				{
    					exp = cexp;
    					diff = cexp - texp;
    					_DST = _TMP;
    				}
    				else if ( texp > cexp )
    				{
    					exp = texp;
    					diff = texp - cexp;
    					_DST = _CPY;
    				}
    				
    				if ( diff )
    				{
    					alup_t _MAN;
    					
    					alup_init_mantissa( &_DST, _MAN );
    						
    					/* Match exponent and align mantissa */
    					(void)alup_set_exponent( &_DST, exp );
    					
    					ret = alup__shr_int2int( &_MAN, diff );
    					
    					truncated = (ret == ERANGE);
    				
    					/* Insert assumed bit back into position */
    					if ( diff < _MAN.bits )
    					{
    						alub_set( _MAN.data, _MAN.bits - diff, 1 );
    					}
    				}
    			}
    			while (0);
    			
    			alup_init_mantissa( &_CPY, _CMAN );
    			alup_init_mantissa( &_TMP, _TMAN );
    			
    			ret = addsub( &_CMAN, &_TMAN );
    			
    			if ( ret == EOVERFLOW )
    			{
    				neg = !neg;
    				alup_neg( &_CMAN );
    			}
    			
    			final = alup_final_bit( &_CMAN );
    			exp = IFTRUE( *(final.ptr) & final.mask, _CMAN.upto - final.bit );
    			
    			if ( exp < _CPY.mdig )
    			{
    				alup__shl_int2int( &_CMAN, _CPY.mdig - exp );
    			}
    			else
    			{
    				alup__shr_int2int( &_CMAN, exp - _CPY.mdig );
    			}
    			
    			alup_set_sign( &_CPY, neg );
    			
    			(void)alup_set_exponent( &_CPY, IFTRUE( exp, exp + bias + (cexp - texp) ) );
    		}
    		
    		ret = alup_mov( _NUM, &_CPY );
    		
    		return IFTRUE( truncated || ret == ERANGE, ERANGE );
    	}
    	
    	return addsub( _NUM, _VAL );
    }

  6. #6
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Well I figured out why the other tests were passing, I had fed the same value into both sides of the operation, fixing that resulted in the expected failures, still haven't figure out where I'm going wrong in the function though

  7. #7
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    OK I think I've nearly got it right on addition & subtraction, somehow missed the bias in the exponent though, anyone able to see where I lost the bias?
    Code:
    typedef int_t (*alup__addsub_int2int)( alup_t const * const _NUM, alup_t const * const _VAL );
    
    int_t alup_addsub
    (
    	alup_t const * const _NUM
    	, alup_t const * const _VAL
    	, void *_cpy
    	, void *_tmp
    	, alup__addsub_int2int addsub
    )
    {
    	if ( alup_floating( _NUM ) || alup_floating( _VAL ) )
    	{
    		int_t ret;
    		alup_t _CPY, _TMP;
    		ssize_t cexp, texp;
    		size_t bits = HIGHEST( _NUM->bits, _VAL->bits );
    		bool_t truncated = false;
    		
    		alup_init_floating( _CPY, _cpy, bits );
    		alup_init_floating( _TMP, _tmp, bits );
    		
    		(void)alup_mov( &_CPY, _NUM );
    		(void)alup_mov( &_TMP, _VAL );
    		
    		cexp = alup_get_exponent( &_CPY );
    		texp = alup_get_exponent( &_TMP );
    		
    		if ( cexp || texp )
    		{
    			bool_t neg = alup_below0( &_CPY );
    			alub_t final;
    			alup_t _CMAN, _TMAN, __CPY, __TMP;
    			size_t bias = alup_get_exponent_bias( &_CPY ), exp = 0, diff = 0;
    			
    			do
    			{
    				alup_t _DST = {0};
    					
    				if ( cexp > texp )
    				{
    					exp = cexp;
    					diff = cexp - texp;
    					_DST = _TMP;
    				}
    				else if ( texp > cexp )
    				{
    					exp = texp;
    					diff = texp - cexp;
    					_DST = _CPY;
    				}
    				else exp = cexp;
    				
    				if ( diff )
    				{
    					alup_t _MAN;
    					
    					alup_init_mantissa( &_DST, _MAN );
    						
    					/* Match exponent and align mantissa */
    					(void)alup_set_exponent( &_DST, exp );
    					
    					ret = alup__shr_int2int( &_MAN, diff );
    					
    					truncated = (ret == ERANGE);
    				
    					/* Insert assumed bit back into position */
    					if ( diff < _MAN.bits )
    					{
    						alub_set( _MAN.data, _MAN.bits - diff, 1 );
    					}
    				}
    			}
    			while (0);
    			
    			/* clear the unneeded values to prevent unexpected behaviour */
    			alup_set_exponent( &_CPY, !!exp && cexp >= texp );
    			alup_set_exponent( &_TMP, !!exp && texp >= cexp );
    			
    			/* Do the actual operation */
    			alup_init_mantissa( &_CPY, _CMAN );
    			alup_init_mantissa( &_TMP, _TMAN );
    			
    			alup_init_unsigned( __CPY, _cpy, _CMAN.upto + 1 );
    			alup_init_unsigned( __TMP, _tmp, _TMAN.upto + 1 );
    			
    			ret = addsub( &__CPY, &__TMP );
    			
    			if ( ret == EOVERFLOW )
    			{
    				neg = !neg;
    				alup_neg( &_CMAN );
    			}
    			
    			final = alup_final_bit( &_CMAN );
    			diff = IFTRUE( *(final.ptr) & final.mask, __CPY.last - final.bit );
    			exp += IFTRUE( neg, diff );
    			exp -= IFTRUE( neg, diff );
    			
    			if ( exp < _CPY.mdig )
    			{
    				alup__shl_int2int( &_CMAN, _CPY.mdig - exp );
    			}
    			else
    			{
    				alup__shr_int2int( &_CMAN, exp - _CPY.mdig );
    			}
    			
    			alup_set_sign( &_CPY, neg );
    			
    			(void)alup_set_exponent( &_CPY, IFTRUE( exp, exp + bias ) );
    		}
    		
    		ret = alup_mov( _NUM, &_CPY );
    		
    		return IFTRUE( truncated || ret == ERANGE, ERANGE );
    	}
    	
    	return addsub( _NUM, _VAL );
    }
    Edit: Forgot to add the output:
    Code:
    make check.run
    ...
    Running suite(s): ALU
    ../tests/check_alu.c:1234: test_alup__op4_floating_incremental_fn() 0.000000 - 64.000000 = -64.000000, got -0.000000
    ../tests/check_alu.c:1244: test_alup__op4_floating_incremental_fn() &_VALUE1 = 0 +0000 00000000 000'0000'0000'0000'0000'0000
    ../tests/check_alu.c:1245: test_alup__op4_floating_incremental_fn() &_VALUE2 = 0 +0006 10000101 000'0000'0000'0000'0000'0000
    ../tests/check_alu.c:1247: test_alup__op4_floating_incremental_fn() &_EXPECT = 1 +0006 10000101 000'0000'0000'0000'0000'0000
    ../tests/check_alu.c:1248: test_alup__op4_floating_incremental_fn() &_RESULT = 1 -0123 00000100 000'0000'0000'0000'0000'0000
    99%: Checks: 4568, Failures: 1, Errors: 0
    ...
    Compilation finished successfully.

  8. #8
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    I think I was still misunderstanding something in the previous iteration, gotta shoot off to work so I'll just dump the code and output.
    Output:
    Code:
    make check.run
    ...
    Running suite(s): ALU
    ../tests/check_alu.c:1234: test_alup__op4_floating_incremental_fn() 0.000000 - 64.000000 = -64.000000, got -32768.000000
    ../tests/check_alu.c:1244: test_alup__op4_floating_incremental_fn() &_VALUE1 = 0 +0000 00000000 000'0000'0000'0000'0000'0000
    ../tests/check_alu.c:1245: test_alup__op4_floating_incremental_fn() &_VALUE2 = 0 +0006 10000101 000'0000'0000'0000'0000'0000
    ../tests/check_alu.c:1247: test_alup__op4_floating_incremental_fn() &_EXPECT = 1 +0006 10000101 000'0000'0000'0000'0000'0000
    ../tests/check_alu.c:1248: test_alup__op4_floating_incremental_fn() &_RESULT = 1 +0015 10001110 000'0000'0000'0000'0000'0000
    99%: Checks: 4568, Failures: 1, Errors: 0
    ...
    Compilation finished successfully.
    Code:
    Code:
    typedef int_t (*alup__addsub_int2int)( alup_t const * const _NUM, alup_t const * const _VAL );
    
    int_t alup_addsub
    (
    	alup_t const * const _NUM
    	, alup_t const * const _VAL
    	, void *_cpy
    	, void *_tmp
    	, bool adding
    )
    {
    	alup__addsub_int2int addsub =
    		adding ? alup__add_int2int : alup__sub_int2int;
    	
    	if ( alup_floating( _NUM ) || alup_floating( _VAL ) )
    	{
    		int_t ret;
    		alup_t _CPY, _TMP, _CEXP, _TEXP, _DST;
    		ssize_t cexp, texp;
    		size_t bits = HIGHEST( _NUM->bits, _VAL->bits );
    		bool_t truncated = false;
    		
    		alup_init_floating( _CPY, _cpy, bits );
    		alup_init_floating( _TMP, _tmp, bits );
    		
    		(void)alup_mov( &_CPY, _NUM );
    		(void)alup_mov( &_TMP, _VAL );
    		
    		/* Get exponents */
    		alup_init_exponent( &_CPY, _CEXP );
    		alup_init_exponent( &_TMP, _TEXP );
    		
    		alup_init___signed( _DST, NULL, bitsof(ssize_t) );
    		
    		_DST.data = &cexp;
    		alup_mov_int2int( &_DST, &_CEXP );
    		
    		_DST.data = &texp;
    		alup_mov_int2int( &_DST, &_TEXP );
    		
    		/* Use exponents */
    		if ( cexp || texp )
    		{
    			alub_t final
    				, csign = alup_final_bit( &_CPY )
    				, tsign = alup_final_bit( &_TMP );
    			bool_t neg
    				, cneg = *(csign.ptr) & csign.mask
    				, tneg = *(tsign.ptr) & tsign.mask;
    			alup_t _CMAN, _TMAN, __CPY, __TMP;
    			size_t //bias = alup_get_exponent_bias( &_CPY ),
    				exp = 0, diff = 0;
    			
    			alup_init_mantissa( &_CPY, _CMAN );
    			alup_init_mantissa( &_TMP, _TMAN );
    			
    			alup_init___signed( __CPY, _cpy, bits );
    			alup_init___signed( __TMP, _tmp, bits );
    			
    			if ( cexp > texp )
    			{
    				exp = cexp;
    				diff = cexp - texp;
    				_DST = __TMP;
    			}
    			else if ( texp > cexp )
    			{
    				exp = texp;
    				diff = texp - cexp;
    				_DST = __CPY;
    			}
    			else exp = cexp;
    			
    			/* Prevent curruption of values by removing unneeded signs */
    			*(csign.ptr) &= ~(csign.mask);
    			*(tsign.ptr) &= ~(tsign.mask);
    			
    			/* Insert assumed bits */
    			alup_set_exponent( &_CPY, !!cexp );
    			alup_set_exponent( &_TMP, !!texp );
    			
    			/* Give more room for less significant binary digits */
    			alup__shl_int2int( &__CPY, _CEXP.bits - adding );
    			alup__shl_int2int( &__TMP, _TEXP.bits - adding );
    			
    			/* Ensure integer representation */
    			if ( cneg ) alup_neg( &__CPY );
    			if ( tneg ) alup_neg( &__TMP );
    			
    			/* Align significant digits to match positions */
    			if ( diff )
    			{
    				_DST.sign = false;
    				ret = alup__shr_int2int( &_DST, diff );
    				truncated = (ret == ERANGE);
    			}
    			
    			ret = addsub( &__CPY, &__TMP );
    			
    			neg = (cneg != tneg || ret == EOVERFLOW);
    			
    			if ( neg ) alup_neg( &__CPY );
    			
    			ret = alup__shr_int2int( &__CPY, _CEXP.bits - adding );
    			truncated = (truncated || ret == ERANGE);
    			
    			final = alup_final_bit( &__CPY );
    			
    			if ( final.bit < _CMAN.last )
    			{
    				diff = (_CMAN.last - final.bit);
    				exp -= diff;
    				exp = IFTRUE( exp >= _CMAN.bits || *(final.ptr) & final.mask, exp );
    				alup__shl_int2int( &_CMAN, diff );
    			}
    			else
    			{
    				diff = (final.bit - _CMAN.last);
    				exp += diff;
    				alup__shr_int2int( &_CMAN, diff );
    			}
    			
    			alup_set_sign( &_CPY, neg );
    			
    			(void)alup_set_exponent( &_CPY, exp );
    		}
    		
    		ret = alup_mov( _NUM, &_CPY );
    		
    		return IFTRUE( truncated || ret == ERANGE, ERANGE );
    	}
    	
    	return addsub( _NUM, _VAL );
    }
    As a reminder the binary values given for each variable are in the format "sign exponent (decimal) exponent (binary) mantissa"

  9. #9
    Registered User
    Join Date
    Sep 2020
    Posts
    425
    Is all your code pushed up to Github? I'm at a loose end and might have a look...

  10. #10
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Quote Originally Posted by hamster_nz View Post
    Is all your code pushed up to Github? I'm at a loose end and might have a look...
    Just uploaded the changes now, got called to start work early (2hrs overtime before my normal hours) so I'll just leave you to it if you're still interested in trying, here's the vid that made me realise a few things I did misunderstand and even gave me ideas for avoiding lost bits, laters for now.

    Addition of single precision floating point numbers - YouTube

  11. #11
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Quote Originally Posted by awsdert View Post
    Just uploaded the changes now, got called to start work early (2hrs overtime before my normal hours) so I'll just leave you to it if you're still interested in trying, here's the vid that made me realise a few things I did misunderstand and even gave me ideas for avoiding lost bits, laters for now.

    Addition of single precision floating point numbers - YouTube
    Well didn't expect much, not that it matters now but sorry I went silent for a while, combination of work and being to into gaming, reading and youtube lead me to leave this to the wayside for a while, on a positive note during that time I roughly figured out in my head where I was going wrong, was a combination of misalignment and misuse of bits and variables, after rectifying that I got passed the first test of 0.0 - 64.0 and now need a little help with ideas for fixing the final bug in the function, for now here's the output and a copy past of the function, I still gotta upload the changes (will do that straight after this post)
    Code:
    make check.run
    ...
    Running suite(s): ALU
    ../tests/check_alu.c:1234: test_alup__op4_floating_incremental_fn() 1.000000 - 65.000000 = -64.000000, got -63.000000
    ../tests/check_alu.c:1244: test_alup__op4_floating_incremental_fn() &_VALUE1 = 0 +0000 01111111 000'0000'0000'0000'0000'0000
    ../tests/check_alu.c:1245: test_alup__op4_floating_incremental_fn() &_VALUE2 = 0 +0006 10000101 000'0010'0000'0000'0000'0000
    ../tests/check_alu.c:1247: test_alup__op4_floating_incremental_fn() &_EXPECT = 1 +0006 10000101 000'0000'0000'0000'0000'0000
    ../tests/check_alu.c:1248: test_alup__op4_floating_incremental_fn() &_RESULT = 1 +0005 10000100 111'1100'0000'0000'0000'0000
    99%: Checks: 4568, Failures: 1, Errors: 0
    ...
    Compilation finished successfully.
    Function:
    Code:
    typedef int_t (*alup__addsub_int2int)( alup_t const * const _NUM, alup_t const * const _VAL );
    
    int_t alup_addsub
    (
    	alup_t const * const _NUM
    	, alup_t const * const _VAL
    	, void *_cpy
    	, void *_tmp
    	, bool adding
    )
    {
    	alup__addsub_int2int addsub =
    		adding ? alup__add_int2int : alup__sub_int2int;
    	
    	if ( alup_floating( _NUM ) || alup_floating( _VAL ) )
    	{
    		int_t ret;
    		alup_t _CPY, _TMP, _CEXP, _TEXP, _DST;
    		ssize_t cexp, texp;
    		size_t bits = HIGHEST( _NUM->bits, _VAL->bits );
    		bool_t truncated = false;
    		
    		alup_init_floating( _CPY, _cpy, bits );
    		alup_init_floating( _TMP, _tmp, bits );
    		
    		(void)alup_mov( &_CPY, _NUM );
    		(void)alup_mov( &_TMP, _VAL );
    		
    		/* Get exponents */
    		alup_init_exponent( &_CPY, _CEXP );
    		alup_init_exponent( &_TMP, _TEXP );
    		
    		alup_init___signed( _DST, NULL, bitsof(ssize_t) );
    		
    		_DST.data = &cexp;
    		alup_mov_int2int( &_DST, &_CEXP );
    		
    		_DST.data = &texp;
    		alup_mov_int2int( &_DST, &_TEXP );
    		
    		/* Use exponents */
    		if ( cexp || texp )
    		{
    			alub_t final
    				, csign = alup_final_bit( &_CPY )
    				, tsign = alup_final_bit( &_TMP )
    				/* Assumed mantissa bits */
    				, cmbit
    				, tmbit;
    			bool_t neg
    				, cneg = *(csign.ptr) & csign.mask
    				, tneg = *(tsign.ptr) & tsign.mask;
    			alup_t _CMAN, _TMAN, __CPY, __TMP;
    			size_t //bias = alup_get_exponent_bias( &_CPY ),
    				exp = 0, diff = 0, shift = (_CEXP.bits - 1) - adding;
    			
    			alup_init_mantissa( &_CPY, _CMAN );
    			alup_init_mantissa( &_TMP, _TMAN );
    			
    			alup_init___signed( __CPY, _cpy, bits );
    			alup_init___signed( __TMP, _tmp, bits );
    			
    			if ( cexp > texp )
    			{
    				exp = cexp;
    				diff = cexp - texp;
    				_DST = __TMP;
    			}
    			else if ( texp > cexp )
    			{
    				exp = texp;
    				diff = texp - cexp;
    				_DST = __CPY;
    			}
    			else exp = cexp;
    			
    			/* Prevent curruption of values by removing unneeded signs */
    			*(csign.ptr) &= ~(csign.mask);
    			*(tsign.ptr) &= ~(tsign.mask);
    			
    			/* Insert assumed bits */
    			cmbit = alup_until_bit( &_CMAN );
    			tmbit = alup_until_bit( &_TMAN );
    			
    			alub_set_val( cmbit, !!cexp );
    			alub_set_val( tmbit, !!texp );
    			
    			/* Minimise potential loss of bits, shift is done on added
    			 * mantissas as well to simplify the exponent correction later*/
    			alup__shl_int2int( &__CPY, shift );
    			alup__shl_int2int( &__TMP, shift );
    			
    			/* Align significant digits to match positions */
    			if ( diff )
    			{
    				_DST.sign = false;
    				ret = alup__shr_int2int( &_DST, diff );
    				truncated = (ret == ERANGE);
    			}
    			
    			/* Convert mantissa/s to integer representation */
    			if ( cneg ) alup_neg( &__CPY );
    			if ( tneg ) alup_neg( &__TMP );
    			
    			ret = addsub( &__CPY, &__TMP );
    			
    			neg = (cneg != tneg || ret == EOVERFLOW);
    			
    			/* Mantissas only hold positive format so switch back for correct
    			 * exponent handling and storage */
    			if ( neg ) alup_neg( &__CPY );
    			
    			final = alup_final_bit_with_val( &__CPY, 1 );
    			
    			if ( final.bit < _CEXP.last )
    			{
    				/* No further bits can be lost, just move bits into position */
    				diff = (_CEXP.last - final.bit);
    				exp -= diff;
    				if ( _CMAN.last < final.bit )
    					alup__shr_int2int( &__CPY, final.bit - _CMAN.last );
    				else
    					alup__shl_int2int( &__CPY, _CMAN.last - final.bit );
    			}
    			else
    			{
    				diff = (final.bit - _CEXP.last);
    				exp += diff;
    				ret = alup__shr_int2int( &__CPY, diff + shift );
    				truncated = (truncated || ret == ERANGE);
    			}
    			
    			alup_set_sign( &_CPY, neg );
    			
    			(void)alup_set_exponent( &_CPY, exp );
    		}
    		
    		ret = alup_mov( _NUM, &_CPY );
    		
    		return IFTRUE( truncated || ret == ERANGE, ERANGE );
    	}
    	
    	return addsub( _NUM, _VAL );
    }

  12. #12
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Managed to fix it somehow, not quite sure how though so if someone feels like analysing the code here's the commit holding the code that passes the tests, the fix however leads me to believe I may have misunderstood some results regarding placing negative numbers in floats, I will be revisiting that after checking the addition is using the new function and works correctly and then correcting the multiplication & probably division functions

    Edit: Whoops forgot to add the link, here it is: GitHub - awsdert/alu at 49162a219cf6f98975f7e07ac77fcc2becbce9a8

  13. #13
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Found a more informative video for FPN multiplication, made some changes to the function I'm using and I think I now how the mantissa correct (at least it looks correct from the raw binary), the exponent is close to being correct but I'm too tired to finish it tonight, will pop the code here with output to see if I get lucky and someone finds the issue by morning, not counting on it but never hurts to try anyways.

    Video:
    Floating Point Arithmetic 2: Multiplication - YouTube

    Output:
    Code:
    make check.run
    ...
    Running suite(s): ALU
    ../tests/check_alu.c:1234: test_alup__op4_floating_incremental_fn() 1.000000 * 129.000000 = 129.000000, got 1.007812
    ../tests/check_alu.c:1244: test_alup__op4_floating_incremental_fn() &_VALUE1 = 0 +0000 01111111 000'0000'0000'0000'0000'0000
    ../tests/check_alu.c:1245: test_alup__op4_floating_incremental_fn() &_VALUE2 = 0 +0007 10000110 000'0001'0000'0000'0000'0000
    ../tests/check_alu.c:1247: test_alup__op4_floating_incremental_fn() &_EXPECT = 0 +0007 10000110 000'0001'0000'0000'0000'0000
    ../tests/check_alu.c:1248: test_alup__op4_floating_incremental_fn() &_RESULT = 0 +0000 01111111 000'0001'0000'0000'0000'0000
    99%: Checks: 4568, Failures: 1, Errors: 0
    ...
    Compilation finished successfully.
    Code:
    Code:
    int_t alup__mul( alup_t const * const _NUM, alup_t const * const _VAL, void *_cpy, void *_tmp )
    {
    	if ( alup_floating( _NUM ) || alup_floating( _VAL ) )
    	{
    		alup_t _DST, _SRC;
    		ssize_t exp, dexp, sexp, bias, bits = _NUM->bits;
    		bool_t dneg, sneg;
    		
    		/* Ensure dealing with just floating numbers */
    		
    		alup_init_floating( _DST, _tmp, bits );
    		alup_mov( &_DST, _NUM );
    		
    		alup_init_floating( _SRC, _NUM->data, bits );
    		_SRC.upto = _NUM->upto;
    		_SRC.last = _NUM->last;
    		_SRC.from = _NUM->from;
    		alup_mov( &_SRC, _VAL );
    		
    		dneg = alup_below0( &_DST );
    		sneg = alup_below0( &_SRC );
    		
    		dexp = alup_get_exponent( &_DST );
    		sexp = alup_get_exponent( &_SRC );
    		
    		if ( !dexp || !sexp )
    		{
    			alup_set( _NUM, 0 );
    			alup_set_sign( &_DST, dneg != sneg );
    			return 0;
    		}
    		
    		bias = alup_get_exponent_bias( &_DST );
    		
    		exp = IFTRUE( dexp, dexp - bias ) + IFTRUE( sexp, sexp - bias );
    		
    		if ( exp >= bias )
    		{	
    			alu_puts("MUL 1");
    			
    			(void)alup_set_fltinf( _NUM, dneg != sneg );
    			return ERANGE;
    		}
    		else
    		{
    			size_t mov;
    			ssize_t dmov, smov;
    			alup_t _DEXP, _SEXP, _DMAN, _SMAN, __DST, __SRC, _DINFER, _SINFER;
    			alub_t final, d1st, s1st, dinfer, sinfer;
    			
    			alup_init_exponent( &_DST, _DEXP );
    			alup_init_exponent( &_SRC, _SEXP );
    			
    			alup_set( &_DEXP, !!dexp );
    			alup_set( &_SEXP, !!sexp );
    			
    			alup_init_mantissa( &_DST, _DMAN );
    			alup_init_mantissa( &_SRC, _SMAN );
    			
    			__DST = _DST;
    			__DST.mdig = 0;
    			__DST.sign = false;
    			
    			__SRC = _SRC;
    			__SRC.mdig = 0;
    			__SRC.sign = false;
    			
    			/* Set position data of assumed bits */
    			_DINFER = __DST;
    			_SINFER = __SRC;
    			
    			_DINFER.from = _DEXP.from;
    			_SINFER.from = _SEXP.from;
    			
    			_DINFER.bits = _DINFER.upto - _DINFER.from;
    			_SINFER.bits = _SINFER.upto - _SINFER.from;
    			
    			dinfer = alup_bit( &_DINFER, _DINFER.from );
    			sinfer = alup_bit( &_SINFER, _SINFER.from );
    			
    			/* Insert assumed bits */
    			alup_set( &_DINFER, 0 );
    			alup_set( &_SINFER, 0 );
    			alub_set_val( dinfer, !!dexp );
    			alub_set_val( sinfer, !!sexp );
    			
    			/* Determine how far to move mantissa to right */
    			d1st = alup_first_bit_with_val( &_DMAN, 1 );
    			s1st = alup_first_bit_with_val( &_SMAN, 1 );
    			
    			dmov = d1st.bit - __DST.from;
    			smov = s1st.bit - __SRC.from;
    	
    			/* Remove useless 0s */
    			(void)alup__shr_int2int( &__DST, dmov );
    			(void)alup__shr_int2int( &__SRC, smov );
    			
    			exp += (_DEXP.from - d1st.bit) + (_SEXP.from - s1st.bit);
    			
    			(void)alup__mul_int2int( &__DST, &__SRC, _cpy );
    			
    			final = alup_final_bit_with_val( &__DST, 1 );
    			
    			if ( final.bit > _DEXP.from )
    			{	
    				/* Normalise */
    				mov = final.bit - _DEXP.from;
    				
    				exp += mov;
    				alup__shr_int2int( &__DST, mov );
    			}
    			else
    			{
    				/* Normalise */
    				mov = _DEXP.from - final.bit;
    				
    				exp -= mov;
    				alup__shl_int2int( &__DST, mov );
    			}
    			
    			alup_set_sign( &_DST, dneg != sneg );
    			alup_set_exponent( &_DST, exp + bias );
    				
    			return alup_mov( _NUM, &_DST );
    		}
    	}
    	
    	return alup__mul_int2int( _NUM, _VAL, _cpy );
    }
    GitHub - awsdert/alu at 234bfe81dc6eb6b1002f887f2b90cc656d7ab37a

  14. #14
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Uncovered & fixed a bug with alup_mov_flt2flt, turned out the mantissa transfer was overriding 1 bit too many and corrupted the exponent as a result, still can't get the final exponent correct though, any ideas from these? GitHub - awsdert/alu at a3933a4aa211569470b623fbe1fca22661741f48

    Output:
    Code:
    make check.run
    ...
    Running suite(s): ALU
    ../src/alup.c:1884: alup__mul() 'Before Move'
    ../src/alup.c:1885: alup__mul() _NUM = 0 +0000 00000000 000'0000'0000'0000'0000'0000
    ../src/alup.c:1888: alup__mul() 'After Move'
    ../src/alup.c:1889: alup__mul() &_DST = 0 +0000 00000000000 '0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000
    ../src/alup.c:1884: alup__mul() 'Before Move'
    ../src/alup.c:1885: alup__mul() _NUM = 0 +0000 01111111 000'0000'0000'0000'0000'0000
    ../src/alup.c:1888: alup__mul() 'After Move'
    ../src/alup.c:1889: alup__mul() &_DST = 0 +0000 01111111111 '0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000
    ../src/alup.c:1973: alup__mul() 'Before Shift'
    ../src/alup.c:1974: alup__mul() &_DST = 0 -1022 00000000001 '0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000
    ../src/alup.c:1977: alup__mul() 'After Shift'
    ../src/alup.c:1978: alup__mul() &_DST = 0 +0000 00000000000 '0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0010
    ../src/alup.c:1982: alup__mul() 'Before Multiply'
    ../src/alup.c:1983: alup__mul() &_DST = 0 +0000 00000000000 '0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0010
    ../src/alup.c:1985: alup__mul() 'After Multiply'
    ../src/alup.c:1986: alup__mul() &_DST = 0 +0000 00000000000 '0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0001'0000'0010
    ../src/alup.c:2001: alup__mul() 'final.bit < _DEXP.from'
    ../tests/check_alu.c:1234: test_alup__op4_floating_incremental_fn() 1.000000 * 129.000000 = 129.000000, got 0.000000
    ../tests/check_alu.c:1244: test_alup__op4_floating_incremental_fn() &_VALUE1 = 0 +0000 01111111 000'0000'0000'0000'0000'0000
    ../tests/check_alu.c:1245: test_alup__op4_floating_incremental_fn() &_VALUE2 = 0 +0007 10000110 000'0001'0000'0000'0000'0000
    ../tests/check_alu.c:1247: test_alup__op4_floating_incremental_fn() &_EXPECT = 0 +0007 10000110 000'0001'0000'0000'0000'0000
    ../tests/check_alu.c:1248: test_alup__op4_floating_incremental_fn() &_RESULT = 0 +0000 00000000 000'0000'0000'0000'0000'0000
    99%: Checks: 4568, Failures: 1, Errors: 0
    ...
    Compilation finished successfully.
    Code:
    Code:
    int_t alup__mul( alup_t const * const _NUM, alup_t const * const _VAL, void *_cpy, void *_tmp )
    {
    	if ( alup_floating( _NUM ) || alup_floating( _VAL ) )
    	{
    		alup_t _DST, _SRC;
    		ssize_t exp, dexp, sexp, bias, bits = _NUM->bits;
    		bool_t dneg, sneg;
    		
    		/* Ensure dealing with just floating numbers */
    		
    		alu_puts("Before Move");
    		alup_print( _NUM, 0, 1 );
    		alup_init_floating( _DST, _tmp, bits * 2 );
    		alup_mov( &_DST, _NUM );
    		alu_puts("After Move");
    		alup_print( &_DST, 0, 1 );
    		
    		alup_init_floating( _SRC, _NUM->data, bits );
    		_SRC.upto = _NUM->upto;
    		_SRC.last = _NUM->last;
    		_SRC.from = _NUM->from;
    		alup_mov( &_SRC, _VAL );
    		
    		dneg = alup_below0( &_DST );
    		sneg = alup_below0( &_SRC );
    		
    		dexp = alup_get_exponent( &_DST );
    		sexp = alup_get_exponent( &_SRC );
    		
    		if ( !dexp || !sexp )
    		{
    			alup_set( _NUM, 0 );
    			alup_set_sign( &_DST, dneg != sneg );
    			return 0;
    		}
    		
    		bias = alup_get_exponent_bias( &_DST );
    		
    		exp = IFTRUE( dexp, dexp - bias ) + IFTRUE( sexp, sexp - bias );
    		
    		if ( exp >= bias )
    		{	
    			alu_puts("MUL 1");
    			
    			(void)alup_set_fltinf( _NUM, dneg != sneg );
    			return ERANGE;
    		}
    		else
    		{
    			size_t mov;
    			ssize_t dmov, smov;
    			alup_t _DEXP, _SEXP, _DMAN, _SMAN, __DST, __SRC, _DINFER, _SINFER;
    			alub_t final, d1st, s1st, dinfer, sinfer;
    			
    			alup_init_exponent( &_DST, _DEXP );
    			alup_init_exponent( &_SRC, _SEXP );
    			
    			alup_set( &_DEXP, !!dexp );
    			alup_set( &_SEXP, !!sexp );
    			
    			alup_init_mantissa( &_DST, _DMAN );
    			alup_init_mantissa( &_SRC, _SMAN );
    			
    			__DST = _DST;
    			__DST.mdig = 0;
    			__DST.sign = false;
    			
    			__SRC = _SRC;
    			__SRC.mdig = 0;
    			__SRC.sign = false;
    			
    			/* Set position data of assumed bits */
    			_DINFER = __DST;
    			_SINFER = __SRC;
    			
    			_DINFER.from = _DEXP.from;
    			_SINFER.from = _SEXP.from;
    			
    			_DINFER.bits = _DINFER.upto - _DINFER.from;
    			_SINFER.bits = _SINFER.upto - _SINFER.from;
    			
    			dinfer = alup_bit( &_DINFER, _DINFER.from );
    			sinfer = alup_bit( &_SINFER, _SINFER.from );
    			
    			/* Insert assumed bits */
    			alup_set( &_DINFER, 0 );
    			alup_set( &_SINFER, 0 );
    			alub_set_val( dinfer, !!dexp );
    			alub_set_val( sinfer, !!sexp );
    			
    			/* Determine how far to move mantissa to right */
    			d1st = alup_first_bit_with_val( &_DMAN, 1 );
    			s1st = alup_first_bit_with_val( &_SMAN, 1 );
    			
    			dmov = d1st.bit - __DST.from;
    			smov = s1st.bit - __SRC.from;
    	
    			/* Remove useless 0s */
    			
    			alu_puts("Before Shift");
    			alup_print( &_DST, 0, 1 );
    			(void)alup__shr_int2int( &__DST, dmov );
    			(void)alup__shr_int2int( &__SRC, smov );
    			alu_puts("After Shift");
    			alup_print( &_DST, 0, 1 );
    			
    			exp += (_DEXP.from - d1st.bit) + (_SEXP.from - s1st.bit) + !!dexp + !!sexp;
    			
    			alu_puts("Before Multiply");
    			alup_print( &_DST, 0, 1 );
    			(void)alup__mul_int2int( &__DST, &__SRC, _cpy );
    			alu_puts("After Multiply");
    			alup_print( &_DST, 0, 1 );
    			
    			/* Normalise */
    			final = alup_final_bit_with_val( &__DST, 1 );
    			
    			if ( final.bit > _DEXP.from )
    			{
    				alu_puts("final.bit > _DEXP.from");
    				mov = final.bit - _DEXP.from;
    				
    				exp += mov;
    				alup__shr_int2int( &__DST, mov );
    			}
    			else if ( final.bit < _DEXP.from )
    			{
    				alu_puts("final.bit < _DEXP.from");
    				mov = _DEXP.from - final.bit;
    				
    				exp -= mov;
    				alup__shl_int2int( &__DST, mov );
    			}
    			
    			/* Mantissa is in place so all we need to do is set the exponent
    			 * and sign */
    			alup_set_exponent( &_DST, exp + bias );
    			
    			alup_set_sign( &_DST, dneg != sneg );
    				
    			return alup_mov( _NUM, &_DST );
    		}
    	}
    	
    	return alup__mul_int2int( _NUM, _VAL, _cpy );
    }

  15. #15
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Forgot to use to separate bias's when I switched to assuming the temporary floats where double the size of the initial variables, fixed that and then analysed more of the flow and found that it's only the exponent that's
    going wrong now, here's what I have (including the further analysed flow). GitHub - awsdert/alu at 839a85f8aea19ffd66e5b18fde100f569f5fe7c5

    Code:
    make check.run
    ...
    Running suite(s): ALU
    ../src/alup.c:1884: alup__mul() 'Before Move'
    ../src/alup.c:1885: alup__mul() _NUM = 0 +0000 00000000 000'0000'0000'0000'0000'0000
    ../src/alup.c:1888: alup__mul() 'After Move'
    ../src/alup.c:1889: alup__mul() &_DST = 0 +0000 00000000000 '0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000
    ../src/alup.c:1884: alup__mul() 'Before Move'
    ../src/alup.c:1885: alup__mul() _NUM = 0 +0000 01111111 000'0000'0000'0000'0000'0000
    ../src/alup.c:1888: alup__mul() 'After Move'
    ../src/alup.c:1889: alup__mul() &_DST = 0 +0000 01111111111 '0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000
    ../src/alup.c:1974: alup__mul() 'Before 1st Shift'
    ../src/alup.c:1975: alup__mul() &_DST = 0 -1022 00000000001 '0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000
    ../src/alup.c:1978: alup__mul() 'After 1st Shift'
    ../src/alup.c:1979: alup__mul() &_DST = 0 +0000 00000000000 '0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0010
    ../src/alup.c:1983: alup__mul() 'Before Multiply'
    ../src/alup.c:1984: alup__mul() &_DST = 0 +0000 00000000000 '0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0010
    ../src/alup.c:1986: alup__mul() 'After Multiply'
    ../src/alup.c:1987: alup__mul() &_DST = 0 +0000 00000000000 '0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0001'0000'0010
    ../src/alup.c:1992: alup__mul() 'Before 2nd Shift'
    ../src/alup.c:1993: alup__mul() &_DST = 0 +0000 00000000000 '0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0001'0000'0010
    ../src/alup.c:2004: alup__mul() 'final.bit < _DEXP.from'
    ../src/alup.c:2011: alup__mul() 'After 2nd Shift'
    ../src/alup.c:2012: alup__mul() &_DST = 0 -1022 00000000001 '0000'0010'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000
    ../src/alup.c:2018: alup__mul() 'After Setting Exponent'
    ../src/alup.c:2019: alup__mul() &_DST = 0 +0017 10000010000 '0000'0010'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000
    ../src/alup.c:2023: alup__mul() 'After Setting Sign'
    ../src/alup.c:2024: alup__mul() &_DST = 0 +0017 10000010000 '0000'0010'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000
    ../tests/check_alu.c:1234: test_alup__op4_floating_incremental_fn() 1.000000 * 129.000000 = 129.000000, got 132096.000000
    ../tests/check_alu.c:1244: test_alup__op4_floating_incremental_fn() &_VALUE1 = 0 +0000 01111111 000'0000'0000'0000'0000'0000
    ../tests/check_alu.c:1245: test_alup__op4_floating_incremental_fn() &_VALUE2 = 0 +0007 10000110 000'0001'0000'0000'0000'0000
    ../tests/check_alu.c:1247: test_alup__op4_floating_incremental_fn() &_EXPECT = 0 +0007 10000110 000'0001'0000'0000'0000'0000
    ../tests/check_alu.c:1248: test_alup__op4_floating_incremental_fn() &_RESULT = 0 +0017 10010000 000'0001'0000'0000'0000'0000
    99%: Checks: 4568, Failures: 1, Errors: 0
    ...
    Compilation finished successfully.
    Code:
    Code:
    int_t alup__mul( alup_t const * const _NUM, alup_t const * const _VAL, void *_cpy, void *_tmp )
    {
    	if ( alup_floating( _NUM ) || alup_floating( _VAL ) )
    	{
    		alup_t _DST, _SRC;
    		ssize_t exp, dexp, sexp, dbias, sbias, bits = _NUM->bits;
    		bool_t dneg, sneg;
    		
    		/* Ensure dealing with just floating numbers */
    		
    		alu_puts("Before Move");
    		alup_print( _NUM, 0, 1 );
    		alup_init_floating( _DST, _tmp, bits * 2 );
    		alup_mov( &_DST, _NUM );
    		alu_puts("After Move");
    		alup_print( &_DST, 0, 1 );
    		
    		alup_init_floating( _SRC, _NUM->data, bits );
    		_SRC.upto = _NUM->upto;
    		_SRC.last = _NUM->last;
    		_SRC.from = _NUM->from;
    		alup_mov( &_SRC, _VAL );
    		
    		dneg = alup_below0( &_DST );
    		sneg = alup_below0( &_SRC );
    		
    		dexp = alup_get_exponent( &_DST );
    		sexp = alup_get_exponent( &_SRC );
    		
    		if ( !dexp || !sexp )
    		{
    			alup_set( _NUM, 0 );
    			alup_set_sign( &_DST, dneg != sneg );
    			return 0;
    		}
    		
    		dbias = alup_get_exponent_bias( &_DST );
    		sbias = alup_get_exponent_bias( &_SRC );
    		
    		exp = IFTRUE( dexp, dexp - dbias ) + IFTRUE( sexp, sexp - sbias );
    		
    		if ( exp >= dbias )
    		{	
    			alu_puts("MUL 1");
    			
    			(void)alup_set_fltinf( _NUM, dneg != sneg );
    			return ERANGE;
    		}
    		else
    		{
    			size_t mov;
    			ssize_t dmov, smov;
    			alup_t _DEXP, _SEXP, _DMAN, _SMAN, __DST, __SRC, _DINFER, _SINFER;
    			alub_t final, d1st, s1st, dinfer, sinfer;
    			
    			alup_init_exponent( &_DST, _DEXP );
    			alup_init_exponent( &_SRC, _SEXP );
    			
    			alup_set( &_DEXP, !!dexp );
    			alup_set( &_SEXP, !!sexp );
    			
    			alup_init_mantissa( &_DST, _DMAN );
    			alup_init_mantissa( &_SRC, _SMAN );
    			
    			__DST = _DST;
    			__DST.mdig = 0;
    			__DST.sign = false;
    			
    			__SRC = _SRC;
    			__SRC.mdig = 0;
    			__SRC.sign = false;
    			
    			/* Set position data of assumed bits */
    			_DINFER = __DST;
    			_SINFER = __SRC;
    			
    			_DINFER.from = _DEXP.from;
    			_SINFER.from = _SEXP.from;
    			
    			_DINFER.bits = _DINFER.upto - _DINFER.from;
    			_SINFER.bits = _SINFER.upto - _SINFER.from;
    			
    			dinfer = alup_bit( &_DINFER, _DINFER.from );
    			sinfer = alup_bit( &_SINFER, _SINFER.from );
    			
    			/* Insert assumed bits */
    			alup_set( &_DINFER, 0 );
    			alup_set( &_SINFER, 0 );
    			alub_set_val( dinfer, !!dexp );
    			alub_set_val( sinfer, !!sexp );
    			
    			/* Determine how far to move mantissa to right */
    			d1st = alup_first_bit_with_val( &_DMAN, 1 );
    			s1st = alup_first_bit_with_val( &_SMAN, 1 );
    			
    			dmov = d1st.bit - __DST.from;
    			smov = s1st.bit - __SRC.from;
    	
    			/* Remove useless 0s */
    			
    			alu_puts("Before 1st Shift");
    			alup_print( &_DST, 0, 1 );
    			(void)alup__shr_int2int( &__DST, dmov );
    			(void)alup__shr_int2int( &__SRC, smov );
    			alu_puts("After 1st Shift");
    			alup_print( &_DST, 0, 1 );
    			
    			exp += (_DEXP.from - d1st.bit) + (_SEXP.from - s1st.bit) + !!dexp + !!sexp;
    			
    			alu_puts("Before Multiply");
    			alup_print( &_DST, 0, 1 );
    			(void)alup__mul_int2int( &__DST, &__SRC, _cpy );
    			alu_puts("After Multiply");
    			alup_print( &_DST, 0, 1 );
    			
    			/* Normalise */
    			final = alup_final_bit_with_val( &__DST, 1 );
    			
    			alu_puts("Before 2nd Shift");
    			alup_print( &_DST, 0, 1 );
    			if ( final.bit > _DEXP.from )
    			{
    				alu_puts("final.bit > _DEXP.from");
    				mov = final.bit - _DEXP.from;
    				
    				//exp += mov;
    				alup__shr_int2int( &__DST, mov );
    			}
    			else
    			{
    				alu_puts("final.bit < _DEXP.from");
    				mov = _DEXP.from - final.bit;
    				
    				//exp -= mov;
    				alup__shl_int2int( &__DST, mov );
    			}
    			
    			alu_puts("After 2nd Shift");
    			alup_print( &_DST, 0, 1 );
    			
    			/* Mantissa is in place so all we need to do is set the exponent
    			 * and sign */
    			alup_set_exponent( &_DST, exp + dbias );
    			
    			alu_puts("After Setting Exponent");
    			alup_print( &_DST, 0, 1 );
    			
    			alup_set_sign( &_DST, dneg != sneg );
    			
    			alu_puts("After Setting Sign");
    			alup_print( &_DST, 0, 1 );
    				
    			return alup_mov( _NUM, &_DST );
    		}
    	}
    	
    	return alup__mul_int2int( _NUM, _VAL, _cpy );
    }
    Any ideas?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 0
    Last Post: 03-09-2016, 03:58 PM
  2. Replies: 11
    Last Post: 08-25-2008, 12:01 PM
  3. Stupid Error That I'm Drawing a Blank On
    By DarkDot in forum C++ Programming
    Replies: 2
    Last Post: 05-07-2007, 06:34 PM
  4. upper case to lower case problem
    By Jasonymk in forum C++ Programming
    Replies: 3
    Last Post: 04-27-2003, 05:35 AM
  5. IDEA: A basic drawing program
    By ygfperson in forum Contests Board
    Replies: 0
    Last Post: 08-12-2002, 11:15 PM

Tags for this Thread