Seem to have got it this time, however ran a test just before this post with fpn set to 14 and got different results so only halfway there:
Code:
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include <inttypes.h>
#include <float.h>
typedef unsigned char uchar;
typedef unsigned long long ullong;
#define bitsof(T) (sizeof(T) * CHAR_BIT)
#define FPNT float
#define FPNT_MAN_BIT 23
#define FPNT_EXP_BIT ((bitsof(FPNT) - FPNT_MAN_BIT) - 1)
#define FPNT_EXP_MAX FLT_MAX_EXP
typedef union LDBL {
FPNT fpn;
uchar hex[sizeof(FPNT)];
struct {
ulong man : FPNT_MAN_BIT;
ulong exp : FPNT_EXP_BIT;
ulong sig : 1;
};
} LDBL;
void print( char *text, LDBL val ) {
printf("%s",text);
for ( size_t i = 0; i < sizeof(FPNT); ++i ) {
printf( " %02X", val.hex[i] );
}
}
int main() {
ulong num = 3, fpn = 0, exp = 0;
ulong pos = 0;
LDBL test = {0}, mine = {0};
test.fpn = fpn;
test.fpn /= 10;
test.fpn += num;
printf("%E\n", test.fpn);
mine.man = num;
if ( num ) {
for ( ++pos ; pos < FPNT_MAN_BIT; ++pos ) {
num /= 10;
if ( !num ) break;
}
mine.exp = pos - 1;
}
mine.exp += FPNT_EXP_MAX;
if ( exp )
mine.exp = (mine.exp == (FPNT_EXP_MAX * 2)) ? -1 : mine.exp + exp;
printf( "test.exp %08X\nmine.exp %08X\n", test.exp, mine.exp );
exp = pos;
num = 10;
while ( --exp ) num *= 10;
for ( ; pos < FPNT_MAN_BIT; ++pos ) {
fpn *= 2;
mine.man <<= 1;
if ( fpn > num ) {
mine.man |= 1u;
fpn -= (fpn % num);
}
}
printf( "test.man %08X\nmine.man %08X\n", test.man, mine.man );
print( "test.hex", test );
putchar('\n');
print( "mine.hex", mine );
putchar('\n');
return 0;
}