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;
}
}