#ifndef INT_TO_FLOAT_H #define INT_TO_FLOAT_H /* Taken from here: */ /* https://android.googlesource.com/toolchain/gcc/+/master/gcc-4.9/libgcc/config/m68k/fpgnulib.c */ /* the following deal with IEEE single-precision numbers */ #define EXCESS 126L #define SIGNBIT 0x80000000L #define HIDDEN (1L << 23L) #define SIGN(fp) ((fp) & SIGNBIT) #define EXP(fp) (((fp) >> 23L) & 0xFF) #define MANT(fp) (((fp) & 0x7FFFFFL) | HIDDEN) #define PACK(s,e,m) ((s) | ((e) << 23L) | (m)) /* the following deal with IEEE double-precision numbers */ #define EXCESSD 1022L #define HIDDEND (1L << 20L) #define EXPDBITS 11 #define EXPDMASK 0x7FFL #define EXPD(fp) (((fp.l.upper) >> 20L) & 0x7FFL) #define SIGND(fp) ((fp.l.upper) & SIGNBIT) #define MANTD(fp) (((((fp.l.upper) & 0xFFFFF) | HIDDEND) << 10) | \ (fp.l.lower >> 22)) #define MANTDMASK 0xFFFFFL /* mask of upper part */ union double_long { double d; struct { long upper; unsigned long lower; } l; }; /* convert unsigned int to double */ double __floatunsidf (unsigned long a1) { long exp = 32 + EXCESSD; union double_long dl; if (!a1) { dl.l.upper = dl.l.lower = 0; return dl.d; } while (a1 < 0x2000000L) { a1 <<= 4; exp -= 4; } while (a1 < 0x80000000L) { a1 <<= 1; exp--; } /* pack up and go home */ dl.l.upper = exp << 20L; dl.l.upper |= (a1 >> 11L) & ~HIDDEND; dl.l.lower = a1 << 21L; return dl.d; } /* convert int to double */ double __floatsidf (long a1) { long sign = 0, exp = 31 + EXCESSD; union double_long dl; if (!a1) { dl.l.upper = dl.l.lower = 0; return dl.d; } if (a1 < 0) { sign = SIGNBIT; a1 = (long)-(unsigned long)a1; if (a1 < 0) { dl.l.upper = SIGNBIT | ((32 + EXCESSD) << 20L); dl.l.lower = 0; return dl.d; } } while (a1 < 0x1000000L) { a1 <<= 4; exp -= 4; } while (a1 < 0x40000000L) { a1 <<= 1; exp--; } /* pack up and go home */ dl.l.upper = sign; dl.l.upper |= exp << 20L; dl.l.upper |= (a1 >> 10L) & ~HIDDEND; dl.l.lower = a1 << 22L; return dl.d; } /* convert unsigned int to float */ float __floatunsisf (unsigned long l) { double foo = __floatunsidf (l); return foo; } /* convert int to float */ float __floatsisf (long l) { double foo = __floatsidf (l); return foo; } #endif /* INT_TO_FLOAT_H */