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