Thanks for the link, read some of it but need to brush up on my math symbols for the other part.
For now I will put aside the mantissa and ask if I'm handling the exponent correctly:
Code:
typedef union ldb_union {
ldb f;
ub b[sizeof(ldb)];
} ldb_union_t;
int string_from_ldb(
string_t *dst,
_Bool lcase,
_Bool withE,
size_t base,
register ldb val ) {
register size_t i, j, cap;
register char c;
register char const *base_txt = lcase ? l_lower_base : l_upper_base;
int ret = string_chk( dst );
string_t string;
ub neg = 0;
ub exp_neg_bit = (ub)SCHAR_MIN >> 1;
ud exp = 0;
ud dig = CHAR_BIT - 1;
uq man = 0;
ldb_union_t fpn = {val};
if ( ret != 0 )
return ret;
i = sizeof(ldb) - 1;
neg = fpn.b[i] & SCHAR_MIN & exp_neg_bit;
if ( neg )
fpn.b[i] ^= neg;
exp = fpn.b[i];
while ( i && dig < LDBL_DIG ) {
exp <<= CHAR_BIT;
exp |= fpn.b[--i];
dig += CHAR_BIT;
}
while ( dig > LDBL_DIG ) {
man <<= 1;
man |= exp & 1;
exp >>= 1;
--dig;
}
if ( neg & exp_neg_bit ) {
neg ^= exp_neg_bit;
exp |= DD_MIN;
}
while ( i-- ) {
man <<= CHAR_BIT;
man |= fpn.b[i];
}
if ( neg ) {
dst->block[0] = '-';
string = string_pos( dst, 1, dst->count - 1 );
}
else string = *dst;
ret = string_from_uq( &string, lcase, base, man );
dst->count = string.count + (neg != 0);
i = dst->count + 1;
if ( i == dst->total && ret != 0 )
ret = ENOMEM;
if ( ret != 0 )
return ret;
/* Process Exponent */
if ( withE ) {
dst->block[i-1] = ((dd)exp < 0) ? '-' : '+';
string = string_pos( dst, i, 0 );
ret = string_from_dq( &string, lcase, base, (dd)exp );
dst->count += string.count;
return ret;
}
if ( (dd)exp < 0 ) {
exp = -((dd)exp);
if ( exp < dst->count )
return 0;
i = exp + 1;
dst->count += i;
if ( dst->count >= dst->total ) {
dst->count -= i;
return ENOMEM;
}
(void)memmove( &dst->block[i], dst->block, dst->count );
dst->block[0] = '0';
dst->block[1] = '.';
for ( i = 0, --exp; i < exp; ++i ) {
dst->block[i] = '0';
}
return 0;
}
while ( exp-- ) {
if ( i == dst->total ) { ret = ENOMEM; --i; break; }
dst->block[i++] = '0';
}
if ( !strncat( dst->block, ".0", dst->total ) )
ret = ENOMEM;
else i += 2;
dst->count = i;
return ret;
}