Well I made some more changes and got as far as this:
Code:
gcc -Wall -o "test_fpn" "test_fpn.c" && "./test_fpn"
test.exp 00 mine.exp 00 test.man 000000 mine.man 000000 test.fpn 0.000000e+00 mine.fpn 0.000000e+00 text '0'
test.exp 7F mine.exp 7F test.man 000000 mine.man 000000 test.fpn 1.000000e+00 mine.fpn 1.000000e+00 text '1'
test.exp 85 mine.exp 85 test.man 4A0000 mine.man 4A0000 test.fpn 1.010000e+02 mine.fpn 1.010000e+02 text '101'
test.exp 7B mine.exp 7B test.man 4CCCCD mine.man 4CCCCD test.fpn 1.000000e-01 mine.fpn 1.000000e-01 text '0.1'
test.exp 78 mine.exp 78 test.man 23D70A mine.man 23D70B test.fpn 1.000000e-02 mine.fpn 1.000000e-02 text '0.01'
test.exp 75 mine.exp 75 test.man 03126F mine.man 03126F test.fpn 1.000000e-03 mine.fpn 1.000000e-03 text '0.001'
test.exp 7B mine.exp 75 test.man 4ED917 mine.man 3645A2 test.fpn 1.010000e-01 mine.fpn 1.390625e-03 text '0.101'
Compilation finished successfully.
Code:
LDBL makeFPN( ullong num, ullong fpn, long exp, ulong dig ) {
	LDBL dst = {0};
	ulong DIG;
	long base = 10, pos = 0,
		pos_max = FPNT_MAN_BIT,
		exp_max = FPNT_EXP_MAX;
	ullong one, dec = 0, NUM;
	if ( !dig ) return dst;
	if ( num == 1 ) {
		dst.exp = exp_max - 1;
		num = 0;
	}
	if ( !fpn && !num ) return dst;
	dst.man = num;
	dst.exp = exp_max;
	for ( NUM = num; NUM > 1; ++pos, NUM >>= 1 );
	for ( NUM = num, --dig;	NUM >= base; --dig, NUM /= base );
	for ( one = 1, DIG = dig; DIG; one *= base, --DIG );
#if 0
	if ( !num ) for ( DIG = dig, pos = -1; DIG; --pos, --DIG );
#else
	if ( !num ) for ( NUM = one, pos = -1; NUM > 1; --pos, NUM >>= 1 );
#endif
	dst.exp += pos - 1;
	if ( fpn ) dec = 1;
	else fpn = 1;
	for ( ; pos < pos_max; ++pos ) {
		fpn *= 2;
		dst.man <<= 1;
		if ( fpn >= one ) {
			dst.man |= dec;
			fpn -= one;
		}
	}
	if ( dst.man ) {
		if ( dst.exp < (exp_max-1) )
			dst.man++;
		pos = 0;
		for ( ; pos < exp; ++pos, dst.man *= 2 );
		for ( ; pos > exp; --pos, dst.man *= 2 );
	}
	return dst;
}
typedef struct test_val {
	ullong num;
	ullong fpn;
	long exp;
	ulong dig;
} test_val_t;

test_val_t values[] = {
	{0}, {1,0,0,1}, {101,0,0,3},
	{0,1,0,2}, {0,1,0,3}, {0,1,0,4}, {0,101,0,4}, {101,101,0,6},
	{1,0,10,2}, {101,0,10,4}, {0,1,10,2}, {0,101,10,4},
	{1,1,10,2},	{3,14,0}, {3,14,10} };
float floats[] = {
	0, 1, 101,
	0.1, 0.01, 0.001, 0.101, 101.101,
	1.0e+10, 101.0e+10, 0.1e+10, 0.101e+10,
	1.1e+10, 3.14, 3.14e+10 };
char *text[] = {
	"0", "1", "101", "0.1", "0.01", "0.001", "0.101", "101.101",
	"1.0e+10", "101.0e+10", "0.1e+10", "0.101e+10", "1.1e+10",
	"3.14", "3.14e+10"
};
int main() {
	int i;
	LDBL test = {0}, mine = {0};
	test_val_t *val;
	for ( i = 0; i < 7; ++i ) {
		test.fpn = floats[i];
		val = &(values[i]);
		mine = makeFPN( val->num, val->fpn, val->exp, val->dig );
		//printf( "test.sig %u mine.sig %u ", test.sig, mine.sig );
		printf( "test.exp %02X mine.exp %02X ", test.exp, mine.exp );
		printf( "test.man %06X mine.man %06X ", test.man, mine.man );
#if 0
		print( "test.hex", test );
		putchar(' ');
		print( "mine.hex", mine );
		putchar(' ');
#endif
		printf("test.fpn %e mine.fpn %e text '%s'\n", test.fpn, mine.fpn, text[i] );
	}
	return 0;
}
So seemingly I need to make 1 more change and I'll have the right algorithm for base 10, checking it works for base 2 & 16 will come after I make that change and ensure all my other values appear correctly, the problem right now is I don't know what change to make.