Sure. Fraction type is real value times power of two (31 in your case), then convert result from FP to integer. So to convert it back you need to convert your fraction back to float and divide by power of two.

float f = (float)frac / 2147483648.0;

or

float f = (float)frac * 0.4656612873077392578125E-9; // use multiply by reciprocal of 2^31

or even more faster using ldexp() function from math.h

float f = ldexp(frac, -31);

ldexp multiplies first argument by 2^N, where N is second ldexp argument. ldexp() should be lot faster than multiply on MCUs without FP coprocessor.

Before using it please check ldexp() works well with 0.0 as first argument. I saw few not cheap compilers having implemented it wrong, unexpected results doing something like ldexp(0.0, -30). When first argument is 0.0 should return 0.0 no matter what is 2nd argument.

No, unless compiler supports nonstandard extension and nonstandard tFrac32 type. In C++ you could probably create tFrac32 class and define typecast operator for it.

Sure. Fraction type is real value times power of two (31 in your case), then convert result from FP to integer. So to convert it back you need to convert your fraction back to float and divide by power of two.

float f = (float)frac / 2147483648.0;

or

float f = (float)frac * 0.4656612873077392578125E-9; // use multiply by reciprocal of 2^31

or even more faster using ldexp() function from math.h

float f = ldexp(frac, -31);

ldexp multiplies first argument by 2^N, where N is second ldexp argument. ldexp() should be lot faster than multiply on MCUs without FP coprocessor.

Before using it please check ldexp() works well with 0.0 as first argument. I saw few not cheap compilers having implemented it wrong, unexpected results doing something like ldexp(0.0, -30). When first argument is 0.0 should return 0.0 no matter what is 2nd argument.