added int_to_float.h as might be needed in future for new sort alg idea

This commit is contained in:
Richard Thier 2022-10-10 19:56:55 +02:00
parent d0843cbc40
commit 57e328897a

118
int_to_float.h Normal file
View File

@ -0,0 +1,118 @@
#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 */