Thread: I can't spot my mistake...

  1. #196
    Registered User
    Join Date
    Sep 2020
    Posts
    150
    Is it really necessary to use non-standard headers like uchar.h and non-standard types like ssize_t ?

  2. #197
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Quote Originally Posted by thmm View Post
    Is it really necessary to use non-standard headers like uchar.h and non-standard types like ssize_t ?
    They ARE standard headers, it's just MS being an ass trying to force everyone to use their private s**t

  3. #198
    Registered User
    Join Date
    Sep 2020
    Posts
    150
    It has nothing to do with MS. Neither MinGW nor cygwin have these

  4. #199
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    948
    ssize_t is part of the POSIX standard, not the C standard. And uchar.h is only in C11 and later (which MS doesn't support).

  5. #200
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Quote Originally Posted by christop View Post
    ssize_t is part of the POSIX standard, not the C standard. And uchar.h is only in C11 and later (which MS doesn't support).
    C11 is still a standard so my statement stands true there, also MS DOES support ssize_t in the form of think it was SSIZE_T, I forgot about it until the recent posts, as soon as I get round to it I will adapt the unic headers to include that part, as for the uchar.h, I'll look into the work around (this is why I want to create the unic library, b****y MS and its private crap)

  6. #201
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by christop
    And uchar.h is only in C11 and later (which MS doesn't support).
    MSVC now supports C11 and C17, though only very recently with one of their updates to Visual Studio 2019.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #202
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Quote Originally Posted by thmm View Post
    Is it really necessary to use non-standard headers like uchar.h and non-standard types like ssize_t ?
    uchar.h is no longer included under windows for now since the docs say char32_t is a built-in type, SSIZE_TYPE is now mapped to SSIZE_T when the WIN32 api is detected, should fix the ssize_t issue so let me know how you fair

  8. #203
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Found another FPN multiplication bug:
    Code:
    make check.run
    ...
    Running suite(s): ALU
    ../src/alup.c:1524: alup__mul() 'MUL 2.1'
    ...
    ../src/alup.c:1535: alup__mul() 'MUL 2.2'
    ../tests/check_alu.c:842: test_alup__math_floating_absolute_fn() exp_dig = 11, man_dig = 52, 1397677567.000000 * 797987423.000000 = 1115329119875239808.000000, got 579400764218150784.000000
    ../tests/check_alu.c:855: test_alup__math_floating_absolute_fn() _EXPECT = 0 +0059 10000111010 1110111101001110001111011001101110111010000000011111
    ../tests/check_alu.c:856: test_alup__math_floating_absolute_fn() _RESULT = 0 +0059 10000111010 0000000101001110001111011001101110111010000000011111
    99%: Checks: 1532, Failures: 1, Errors: 0
    ...
    Compilation finished successfully.
    I've tried everything I can think of, now I'm fishing for ideas
    Code:
    int_t alup__mul( alup_t _NUM, alup_t _VAL, void *_cpy, void *_tmp )
    {
    	if ( alup_floating( _NUM ) || alup_floating( _VAL ) )
    	{
    		int_t ret;
    		alup_t _DST, _SRC, _DMAN, _SMAN;
    		ssize_t exp, dexp, sexp, dbias, sbias, dbits, sbits, bits, size;
    		bool_t dneg, sneg;
    		ssize_t ddiff = 0, sdiff = 0;
    		size_t man_upto;
    		alub_t final, prior;
    		
    		/* Ensure dealing with just floats, impossible for both to take _tmp
    		 * given the above if statment */
    		
    		if ( alup_floating( _NUM ) )
    		{
    			_DST = _NUM;
    		}
    		else
    		{
    			bits = _NUM.upto - _NUM.from;
    			size = BITS2SIZE( bits );
    			alup_init_floating( _DST, _tmp, size );
    			alup_mov( _DST, _NUM );
    		}
    		
    		if ( alup_floating( _VAL ) )
    		{
    			_SRC = _VAL;
    		}
    		else
    		{
    			bits = _VAL.upto - _VAL.from;
    			size = BITS2SIZE( bits );
    			alup_init_floating( _SRC, _tmp, size );
    			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 )
    		{
    			_NUM.upto--;
    			alup_set( _NUM, 0 );
    			alub_set( _DST.data, _DST.upto - 1, dneg != sneg );
    			return 0;
    		}
    		
    		dbias = alup_get_exponent_bias( _DST );
    		dexp -= dbias;
    		
    		sbias = alup_get_exponent_bias( _DST );
    		sexp -= sbias;
    		
    		exp = dexp + sexp;
    				
    		alup_init_mantissa( _DST, _DMAN );
    		alup_init_mantissa( _SRC, _SMAN );
    		
    		dbits = _DMAN.upto - _DMAN.from;
    		sbits = _SMAN.upto - _SMAN.from;
    		bits = LOWEST( dbits, sbits );
    		
    		ddiff = EITHER( dexp >= 0 && dexp < dbits, dexp, dbits );
    		sdiff = EITHER( sexp >= 0 && sexp < sbits, sexp, sbits );
    		prior = alub( _DST.data, _DST.upto - 1 );
    		*(prior.ptr) &= ~(prior.mask);
    		alub_set( _DST.data, _DST.upto - 1, 0 );
    		alup_set_exponent( _DST, 0 );
    		
    		alub_set( _DST.data, _DMAN.upto, 1 );
    		alub_set( _SRC.data, _SMAN.upto, 1 );
    		
    		man_upto = _DMAN.upto;
    		
    		_SMAN.from = _SMAN.upto - sdiff;
    		_DMAN.upto = _DST.upto;
    		_SMAN.upto++;
    		
    		alup__shr( _DMAN, dbits - ddiff );
    		prior = alup_final_one( _DMAN );
    		
    		ret = alup__mul_int2int( _DMAN, _SMAN, _cpy );
    		
    		/* We mangled this so restore it now */
    		alup_set_exponent( _SRC, sexp + sbias );
    		
    		if ( exp >= dbias )
    		{	
    			alu_puts("MUL 1");
    			
    			/* Set infinity */
    			alup_init_mantissa( _DST, _DMAN );
    			
    			alup_set( _DMAN, 0 );
    			alup_set_exponent( _DST, (dbias << 1) | 1 );
    		}
    		else
    		{	
    			final = alup_final_one( _DMAN );
    			_DMAN.upto = man_upto;
    			
    			if ( final.bit < man_upto - 1 )
    			{
    				/* Normalise */
    				size_t mov = man_upto - final.bit;
    				size_t add = final.bit - prior.bit;
    				
    				alu_puts("MUL 2.1");
    				
    				exp = dexp + add;
    				alup__shl( _DMAN, mov );
    			}
    			else if ( final.bit >= man_upto )
    			{
    				/* Normalise */
    				size_t mov = final.bit - man_upto;
    				size_t add = final.bit - prior.bit;
    				
    				alu_puts("MUL 2.2");
    				
    				exp = dexp + add;
    				alup__shr( _DMAN, mov );
    			}
    			else if ( ret == EOVERFLOW )
    			{
    				alu_puts("MUL 2.3");
    				
    				exp++;
    				alup__shr( _DMAN, 1 );
    				alub_set( _DMAN.data, man_upto - 1, 1 );
    			}
    			
    			alup_set_exponent( _DST, exp + dbias );
    		}
    		
    		alub_set( _DST.data, _DST.upto - 1, dneg != sneg );
    		
    		if ( alup_floating( _NUM ) )
    			return 0;
    			
    		return alup_mov( _NUM, _DST );
    	}
    	
    	return alup__mul_int2int( _NUM, _VAL, _cpy );
    }

  9. #204
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Fixed it, turned out it was because I shortened the length of _DMAN before it needed to be, or rather it didn't need to be at all, now the division shows a bug on the same values, got a funeral to go to soon so will just
    post the output and code before trying to fix it myself in the little time I have left before I leave:
    Code:
    make check.run
    ...
    Running suite(s): ALU
    ../src/alup.c:1745: alup__div() 'Route 2.1'
    ../tests/check_alu.c:841: test_alup__math_floating_absolute_fn() exp_dig = 11, man_dig = 52, 1397677567.000000 / 797987423.000000 = 1.751503, got 576460753243754624.000000
    ../tests/check_alu.c:854: test_alup__math_floating_absolute_fn() _EXPECT = 0 +0000 01111111111 1100000001100010100001000110010100110001101000001110
    ../tests/check_alu.c:855: test_alup__math_floating_absolute_fn() _RESULT = 0 +0059 10000111010 0000000000000000000000000000011100000001100010100001
    99%: Checks: 1532, Failures: 1, Errors: 0
    ...
    Compilation finished successfully.
    Code:
    int_t alup__div( alup_t _NUM, alup_t _VAL, void *_rem, void *_tmp )
    {
    	if ( alup_floating( _NUM ) || alup_floating( _VAL ) )
    	{
    		alup_t _DST, _SRC, _DMAN, _SMAN;
    		size_t exp_len;
    		ssize_t exp, dexp, sexp, dbias, sbias, dbits, sbits, bits, size;
    		bool_t dneg, sneg;
    		alub_t prior;
    		
    		/* Ensure dealing with just floats, impossible for both to take _tmp
    		 * given the above if statment */
    		
    		if ( alup_floating( _NUM ) )
    		{
    			_DST = _NUM;
    		}
    		else
    		{
    			bits = _NUM.upto - _NUM.from;
    			size = BITS2SIZE( bits );
    			alup_init_floating( _DST, _tmp, size );
    			alup_mov( _DST, _NUM );
    		}
    		
    		if ( alup_floating( _VAL ) )
    		{
    			_SRC = _VAL;
    		}
    		else
    		{
    			bits = _VAL.upto - _VAL.from;
    			size = BITS2SIZE( bits );
    			alup_init_floating( _SRC, _tmp, size );
    			alup_mov( _SRC, _VAL );
    		}
    		
    		dneg = alup_below0( _DST );
    		sneg = alup_below0( _SRC );
    		alub_set( _DST.data, _DST.upto - 1, dneg != sneg );
    		
    		dexp = alup_get_exponent( _DST );
    		sexp = alup_get_exponent( _SRC );
    		
    		if ( !dexp || !sexp )
    		{
    			_NUM.upto--;
    			alup_set( _NUM, 0 );
    			return 0;
    		}
    		
    		dbias = alup_get_exponent_bias( _DST );
    		dexp -= dbias;
    		
    		sbias = alup_get_exponent_bias( _DST );
    		sexp -= sbias;
    				
    		alup_init_mantissa( _DST, _DMAN );
    		alup_init_mantissa( _SRC, _SMAN );
    		
    		dbits = _DMAN.upto - _DMAN.from;
    		sbits = _SMAN.upto - _SMAN.from;
    		bits = LOWEST( dbits, sbits );
    		
    		exp_len = (_DST.upto - _DMAN.upto) - 1;
    		_SMAN.from = _SMAN.upto - EITHER( sexp >= 0 && sexp < bits, sexp, bits );
    		
    		alub_set( _SMAN.data, _SMAN.upto, 1 );
    		_DMAN.upto = _DST.upto - 1;
    		_SMAN.upto++;
    		
    		alup__shl( _DMAN, exp_len - 1 );
    		alub_set( _DMAN.data, _DMAN.upto - 1, 1 );
    		
    		prior = alup_final_one( _DMAN );
    		(void)alup__div_int2int( _DMAN, _SMAN, _rem );
    		
    		/* We mangled this so restore it now */
    		alup_set_exponent( _SRC, sexp + sbias );
    		
    		exp = dexp + sexp;
    		
    		if ( exp > dbias )
    		{	
    			alu_puts("Route 1");
    			/* Set infinity */
    			_DMAN.upto = (_DST.upto - exp_len) - 1;
    			alup_set( _DMAN, 0 );
    			alup_set_exponent( _DST, (dbias << 1) | 1 );
    		}
    		else if ( exp <= (ssize_t)(_DMAN.upto - _DMAN.from) )
    		{
    			/* Normalise */
    			alub_t first = alup_first_one( _DMAN ), final = alup_final_one( _DMAN );
    			size_t rel2prv = prior.bit - final.bit
    				, rel2cap = _DMAN.upto - final.bit;
    			bool_t round = (first.bit - _DST.from) < exp_len;
    			
    			if ( rel2prv >= (exp_len-1) )
    			{
    				alu_puts("Route 2.1");
    				alup__shr( _DMAN, (exp_len - 1) );
    				//alup__shr( _DMAN, ((_DMAN.upto - _DST.from) - pos) );
    			}
    			else
    			{
    				//alu_puts("Route 2.2");
    				
    				alup__shr( _DMAN, (exp_len - rel2cap) - 1 );
    				exp = dexp - rel2prv;
    				
    				if ( round )
    				{
    					alup_inc( _DMAN );
    				}
    				
    				alup__shr( _DMAN, 1 );
    			}
    			alup_set_exponent( _DST, exp + dbias );
    		}	
    		else
    		{
    			//alu_puts("Route 3");
    			alup__shr( _DMAN, (exp_len - 1) );
    			alup_set_exponent( _DST, exp + dbias );
    		}
    		
    		if ( alup_floating( _NUM ) )
    			return 0;
    			
    		return alup_mov( _NUM, _DST );
    	}
    	
    	return alup__div_int2int( _NUM, _VAL, _rem );
    }

  10. #205
    Registered User
    Join Date
    Sep 2020
    Posts
    150
    Still no luck with MinGW:
    Alu_demo\alu\_.h|4|fatal error: unic/limits.h: No such file or directory|

  11. #206
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Quote Originally Posted by thmm View Post
    Still no luck with MinGW:
    Alu_demo\alu\_.h|4|fatal error: unic/limits.h: No such file or directory|
    That's strange, have you checked that unic downloaded properly? I know my code there could probably use some work but I need the help of someone used to using git in shell rather than GUI.
    There's no easily discernible reason for it to not find the header when I used -I $(UNIC_INC_DIR) to include the right directory in the search path.

  12. #207
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Fixed the issue, ended up having to dedicate _tmp to _DST, _NUM for _SRC, move _NUM to _DST, _VAL to _SRC afterwards (since have to make sure is a float anyways) and remove the check for _NUM being a float to ensure _DST is moved into _NUM at the end, still get a rounding error however:
    Code:
    make check.run
    ...
    Running suite(s): ALU
    ...
    ../src/alup.c:1732: alup__div() Route 2.1, mov = 7
    ../src/alup.c:1736: alup__div() _DST = 0 -0771 00011111100 01001110110001001110110001001110110001001110110001001110110001001110110001001110110001001110110001001110110001001110
    ../src/alup.c:1740: alup__div() _DST = 0 -1022 00000000001 11111000100111011000100111011000100111011000100111011000100111011000100111011000100111011000100111011000100111011001
    ../tests/check_alu.c:739: test_alup__math_floating_incremental_fn() exp_dig = 11, man_dig = 52, _i = 205, 205.000000 / 13.000000 = 15.769231, got 15.769231
    ../tests/check_alu.c:752: test_alup__math_floating_incremental_fn() _EXPECT = 0 +0003 10000000010 1111100010011101100010011101100010011101100010011110
    ../tests/check_alu.c:753: test_alup__math_floating_incremental_fn() _RESULT = 0 +0003 10000000010 1111100010011101100010011101100010011101100010011101
    99%: Checks: 1532, Failures: 1, Errors: 0
    ...
    Compilation finished successfully.
    Current code (not cleaned up)
    Code:
    int_t alup__div( alup_t _NUM, alup_t _VAL, void *_rem, void *_tmp )
    {
    	if ( alup_floating( _NUM ) || alup_floating( _VAL ) )
    	{
    		alup_t _DST, _SRC, _DMAN, _SMAN;
    		size_t exp_len, man_upto;
    		ssize_t exp, dexp, sexp, dbias, sbias, dbits, sbits, bits, size;
    		bool_t dneg, sneg;
    		alub_t prior;
    		
    		/* Ensure dealing with just floats, impossible for both to take _tmp
    		 * given the above if statment */
    		 
    		bits = (_NUM.upto - _NUM.from) * 2;
    		size = BITS2SIZE( bits );
    		alup_init_floating( _DST, _tmp, size );
    		alup_mov( _DST, _NUM );
    
    		size /= 2;
    		_SRC.data = _NUM.data;
    		_SRC.info = ALU_INFO_FLOAT | ALU_INFO__SIGN;
    		_SRC.from = _NUM.from;
    		_SRC.upto = _NUM.upto;
    		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 )
    		{
    			_NUM.upto--;
    			alup_set( _NUM, 0 );
    			alub_set( _DST.data, _DST.upto - 1, dneg != sneg );
    			return 0;
    		}
    		
    		dbias = alup_get_exponent_bias( _DST );
    		sbias = alup_get_exponent_bias( _DST );
    		
    		dexp -= dbias;
    		sexp -= sbias;
    				
    		alup_init_mantissa( _DST, _DMAN );
    		alup_init_mantissa( _SRC, _SMAN );
    		
    		dbits = _DMAN.upto - _DMAN.from;
    		sbits = _SMAN.upto - _SMAN.from;
    		bits = LOWEST( dbits, sbits );
    		
    		exp_len = (_DST.upto - _DMAN.upto) - 1;
    		_SMAN.from = _SMAN.upto - EITHER( sexp >= 0 && sexp < sbits, sexp, sbits );
    		
    		alub_set( _DST.data, _DMAN.upto, 1 );
    		alub_set( _SRC.data, _SMAN.upto, 1 );
    		
    		man_upto = _DMAN.upto;
    		_DMAN.upto = _DST.upto;
    		_SMAN.upto++;
    		
    		alup__shl( _DMAN, exp_len );
    		prior = alup_final_one( _DMAN );
    		(void)alup__div_int2int( _DMAN, _SMAN, _rem );
    		
    		exp = dexp + sexp;
    		
    		if ( exp > dbias )
    		{	
    			alu_puts("Route 1");
    			/* Set infinity */
    			_DMAN.upto = man_upto;
    			alup_set( _DMAN, 0 );
    			alup_set_exponent( _DST, (dbias << 1) | 1 );
    		}
    		else if ( exp <= (ssize_t)(_DMAN.upto - _DMAN.from) )
    		{
    			/* Normalise */
    			alub_t first = alup_first_one( _DMAN ), final = alup_final_one( _DMAN );
    			size_t rel2prv = prior.bit - final.bit
    				, rel2cap = _DMAN.upto - final.bit, mov, sub;
    			bool_t round = (first.bit - _DST.from) < exp_len;
    			
    			exp = dexp - rel2prv;
    			
    			if ( final.bit > man_upto )
    			{
    				mov = final.bit - man_upto;
    				
    				alu_printf( "Route 2.1, mov = %zu", mov );
    				
    				if ( mov )
    				{
    					alup_print( _DST, 0, 1 );
    					alup__shr( _DMAN, mov - 1 );
    					alup_inc( _DMAN );
    					alup__shr( _DMAN, 1 );
    					alup_print( _DST, 0, 1 );
    				}
    				else
    				{
    					alu_puts("No rounding");
    					alup__shr( _DMAN, mov );
    				}
    			}
    			else if ( final.bit < man_upto )
    			{
    				mov = man_upto - final.bit;
    				
    				alu_puts("Route 2.2");
    				
    				alup__shl( _DMAN, mov - 1 );
    				//exp = dexp - rel2prv;
    				
    				if ( round )
    				{
    					alup_inc( _DMAN );
    				}
    				
    				alup__shr( _DMAN, 1 );
    			}
    			
    			alup_set_exponent( _DST, exp + dbias );
    		}	
    		else
    		{
    			//alu_puts("Route 3");
    			alup__shr( _DMAN, (exp_len - 1) );
    			alup_set_exponent( _DST, exp + dbias );
    		}
    		
    		alub_set( _DST.data, _DST.upto - 1, dneg != sneg );
    			
    		return alup_mov( _NUM, _DST );
    	}
    	
    	return alup__div_int2int( _NUM, _VAL, _rem );
    }
    If anyone has any ideas for fixing the rounding error it would be much appreciated if you post them

  13. #208
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Haven't managed to fix that rounding error as yet but found an example of the FPN subtraction bug I discovered earlier but had the wrong info displayed at the time. Got overtime today, early start tomorrow, gospel after that and possibly overtime for 4 weeks on one of my days off so is unlikely I will feel like looking into this bug until after that so will just post here and see if anyone thinks of something.

    Edited Output:
    Code:
    make check.run
    ...
    Running suite(s): ALU
    ... (17 Off by 1 errors from FPN division)
    ../tests/check_alu.c:1031: test_alup__math_floating_absolute_fn() exp_dig = 11, man_dig = 52, 1327753883.000000 - 1770012269.000000 = -442258386.000000, got 631483438.000000
    ../tests/check_alu.c:1044: test_alup__math_floating_absolute_fn() _EXPECT = 1 +0028 10000011011 1010010111000101001111010010000000000000000000000000
    ../tests/check_alu.c:1045: test_alup__math_floating_absolute_fn() _RESULT = 0 +0029 10000011100 0010110100011101011000010111000000000000000000000000
    99%: Checks: 2560, Failures: 18, Errors: 0
    ...
    Compilation finished successfully.
    Subtraction Function:
    Code:
    int_t alup__sub( alup_t _NUM, alup_t _VAL, void *_cpy, void *_tmp )
    {	
    	if ( alup_floating( _NUM ) || alup_floating( _VAL ) )
    	{
    		int_t ret;
    		alup_t _CPY, _TMP, _CMAN, _TMAN;
    		size_t exp, cexp, texp;
    		size_t
    			bits = HIGHEST( _NUM.upto - _NUM.from, _VAL.upto - _VAL.from )
    			, size = (bits / UNIC_CHAR_BIT) + !!(bits % UNIC_CHAR_BIT);
    		bool_t truncated = false;
    		
    		alup_init_floating( _CPY, _cpy, size );
    		alup_init_floating( _TMP, _tmp, size );
    		
    		alup_init_mantissa( _CPY, _CMAN );
    		alup_init_mantissa( _TMP, _TMAN );
    		
    		alup_mov( _CPY, _NUM );
    		alup_mov( _TMP, _VAL );
    		
    		cexp = alup_get_exponent( _CPY );
    		texp = alup_get_exponent( _TMP );
    		
    		ret = alup_match_exponents( _CPY.data, _TMP.data, size );
    		
    		truncated = (ret == ERANGE);
    		
    		exp = alup_get_exponent( _CPY );
    		
    		ret = alup__sub_int2int( _CMAN, _TMAN );
    		
    		if ( cexp || texp )
    		{
    			size_t bias = alup_get_exponent_bias( _CPY );
    			
    			if ( ret == EOVERFLOW || cexp == texp )
    			{	
    				//size_t both = 1 + (ret == EOVERFLOW && cexp == texp);
    				//alub_t c = alub( _CMAN.data, _CMAN.upto - 1 );
    				
    				--exp;
    				alup__shl( _CMAN, 1 );
    				
    				//*(c.ptr) &= ~(c.mask);
    				//*(c.ptr) |= IFTRUE( both == 2, c.mask );
    			}
    			
    			if ( cexp == texp )
    			{
    				alup_set( _TMP, 0 );
    				
    				_TMP.info = 0;
    				
    				if ( alup_cmp_int2int( _CMAN, _TMP ) == 0 )
    				{
    					if ( ret != EOVERFLOW )
    						exp  = 0;
    				}
    			}
    			
    			alub_set
    			(
    				_CPY.data
    				, _CPY.upto - 1
    				, (cexp >= bias && cexp < texp) || (!cexp && texp >= bias)
    			);
    		}
    		
    		(void)alup_set_exponent( _CPY, exp );
    		
    		ret = alup_mov( _NUM, _CPY );
    		
    		return IFTRUE( truncated || ret == ERANGE, ERANGE );
    	}
    	
    	return alup__sub_int2int( _NUM, _VAL );
    }
    Exponent matching Function:
    Code:
    int_t alup_match_exponents( void *_num, void *_val, size_t size )
    {
    	int_t ret;
    	alup_t _NUM, _VAL, _DST, _MAN = {0};
    	size_t exp = 0, nexp, vexp, diff = 0;
    	bool truncated = false;
    	
    	alup_init_floating( _NUM, _num, size );
    	alup_init_floating( _VAL, _val, size );
    	
    	nexp = alup_get_exponent( _NUM );
    	vexp = alup_get_exponent( _VAL );
    		
    	if ( nexp > vexp )
    	{
    		exp = nexp;
    		diff = nexp - vexp;
    		_DST = _VAL;
    	}
    	else if ( vexp > nexp )
    	{
    		exp = vexp;
    		diff = vexp - nexp;
    		_DST = _NUM;
    	}
    	
    	if ( diff )
    	{
    		alup_init_mantissa( _DST, _MAN );
    			
    		/* Match exponent and align mantissa */
    		(void)alup_set_exponent( _DST, exp );
    		
    		ret = alup__shr( _MAN, diff );
    		
    		truncated = (ret == ERANGE);
    	
    		/* Insert assumed bit back into position */
    		if ( diff < _MAN.upto )
    		{
    			alub_t m = alub( _MAN.data, _MAN.upto - diff );
    			*(m.ptr) |= m.mask;
    		}
    	}
    	
    	return IFTRUE( truncated, ERANGE );
    }
    Addition uses the same exponent matcher on the same values so I doubt it's that, included just in case though

  14. #209
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Didn't have overtime today and when I finally felt like programming I decided to spend the past few hours changing how certain information is recorded in the API, took a while to fix all the superficial errors that popped up as a result, anyways since I couldn't think of how to fix the other bugs I mentioned just yet I decided to check the floating point comparisons are correct, turns out either my comparisons are more accurate or I've misunderstood something critical, 1st of here's the code for the check:
    Code:
    START_TEST( test_alup__cmp_floating_incremental )
    {
    	ck_assert( alu_upto(alu) > 0 );
    	
    	if ( !stop_checks )
    	{
    		int expect, result, _j = _i % per_func;
    		double value1 = _i, value2 = _j;
    		alup_t _VALUE1, _VALUE2;
    		
    		alup_init_floating( _VALUE1, &value1, bitsof(double) );
    		alup_init_floating( _VALUE2, &value2, bitsof(double) );
    		
    		expect = (value1 > value2) - (value1 < value2);
    		result = alup_cmp( &_VALUE1, &_VALUE2 );
    		
    		if ( expect != result )
    		{	
    			alu_printf
    			(
    				"%f <> %f = %i (source: %i <> %i), got %i"
    				, value2
    				, value2
    				, expect
    				, _i
    				, _j
    				, result
    			);
    			
    			alup_print( &_VALUE1, 0, 1 );
    			alup_print( &_VALUE2, 0, 1 );
    			
    			stop_checks = true;
    		}
    		
    		ck_assert( expect == result );
    	}
    }
    END_TEST
    Edited output:
    Code:
    make check.run
    ...
    Running suite(s): ALU
    ../tests/check_alu.c:653: test_alup__cmp_floating_incremental_fn() 0.000000 <> 0.000000 = 1 (source: 64 <> 0), got -1
    ../tests/check_alu.c:664: test_alup__cmp_floating_incremental_fn() &_VALUE1 = 1 -1018 0000000101 0000000000000000000000000000000000000000000000000000
    ../tests/check_alu.c:665: test_alup__cmp_floating_incremental_fn() &_VALUE2 = 0 -2047 0000000000 0000000000000000000000000000000000000000000000000000
    97%: Checks: 2560, Failures: 54, Errors: 0
    ../tests/check_alu.c:424:F:Core:test_alur_set_floating:0: Assertion 'memcmp( V, &src_val, sizeof(double) ) == 0' failed
    ...
    Compilation finished successfully.
    Putting aside the higher level alur tests apparently failing (will look into that later) can anyone tell me why the floating comparison seems to ignore the sign bit?

  15. #210
    Registered User
    Join Date
    Nov 2020
    Posts
    1
    Quote Originally Posted by hamster_nz View Post
    If I was in your position I would really start looking how actual floating point H/W does addition. There are plenty of papers out there:

    https://www.ijert.org/research/desig...TV2IS70837.pdf

    Worktime.com/download/pdf/190942867.pdf

    These sorts of problems tend to need to be written once, and rewritten twice (or 'refactored' if you don't like "rewritten" as a term).

    - The first write is to work out what needs to happen, and it usually is broken and littered with errors in corner cases.

    - The first rewrite is to make it actually work correctly, but is poorly performing and poorly structured.

    - The second rewrite uses are the things learnt along the way to write a clean and efficient implementation.

    You can sometimes jump the first couple of attempts if you read a few published papers, which will point out the corner cases and traps to you.

    Thank You!
    Finaly a nice and angumented answer

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. can anyone help to spot mistake in the code
    By chess_queen in forum C Programming
    Replies: 1
    Last Post: 10-21-2012, 10:37 AM
  2. Can you spot my mistake?
    By Brewer in forum C Programming
    Replies: 13
    Last Post: 11-12-2006, 12:50 PM
  3. going to a certain spot in a file...
    By agerealm in forum C++ Programming
    Replies: 3
    Last Post: 05-17-2002, 02:31 AM

Tags for this Thread