//uspace/trunk/softfloat/include/comparison.h |
---|
35,6 → 35,12 |
inline int isFloat32Infinity(float32 f); |
inline int isFloat32Zero(float32 f); |
inline int isFloat64NaN(float64 d); |
inline int isFloat64SigNaN(float64 d); |
inline int isFloat64Infinity(float64 d); |
inline int isFloat64Zero(float64 d); |
inline int isFloat32eq(float32 a, float32 b); |
inline int isFloat32lt(float32 a, float32 b); |
inline int isFloat32gt(float32 a, float32 b); |
//uspace/trunk/softfloat/include/sftypes.h |
---|
29,7 → 29,6 |
#ifndef __SFTYPES_H__ |
#define __SFTYPES_H__ |
typedef union { |
float f; |
__u32 binary; |
79,6 → 78,7 |
#define FLOAT32_INF 0x7F800000 |
#define FLOAT32_MANTISA_SIZE 23 |
#define FLOAT64_MANTISA_SIZE 52 |
#define FLOAT32_BIAS 0x7F |
#define FLOAT64_BIAS 0x3FF |
//uspace/trunk/softfloat/include/conversion.h |
---|
29,5 → 29,9 |
#ifndef __CONVERSION_H__ |
#define __CONVERSION_H__ |
float64 convertFloat32ToFloat64(float32 a); |
float32 convertFloat64ToFloat32(float64 a); |
#endif |
//uspace/trunk/softfloat/generic/softfloat.c |
---|
71,6 → 71,14 |
return mulFloat32(fa, fb).f; |
} |
float __divsf3(float a, float b) |
{ |
float32 fa, fb; |
fa.f=a; |
fb.f=b; |
// return divFloat32(fa, fb).f; |
}; |
float __negsf2(float a) |
{ |
float32 fa; |
89,6 → 97,19 |
/* Conversion functions */ |
double __extendsfdf2(float a) |
{ |
float32 fa; |
fa.f = a; |
return convertFloat32ToFloat64(fa).d; |
}; |
float __truncdfsf2(double a) |
{ |
float64 da; |
da.d = a; |
return convertFloat64ToFloat32(da).f; |
} |
/* Comparison functions */ |
/* a<b .. -1 |
//uspace/trunk/softfloat/generic/conversion.c |
---|
26,3 → 26,111 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#include "sftypes.h" |
#include "conversion.h" |
float64 convertFloat32ToFloat64(float32 a) |
{ |
float64 result; |
__u64 mant; |
result.parts.sign = a.parts.sign; |
result.parts.mantisa = a.parts.mantisa; |
result.parts.mantisa <<= (FLOAT64_MANTISA_SIZE - FLOAT32_MANTISA_SIZE ); |
if ((isFloat32Infinity(a))||(isFloat32NaN(a))) { |
result.parts.exp = 0x7FF; |
/* TODO; check if its correct for SigNaNs*/ |
return result; |
}; |
result.parts.exp = a.parts.exp + ( (int)FLOAT64_BIAS - FLOAT32_BIAS ); |
if (a.parts.exp == 0) { |
/* normalize denormalized numbers */ |
if (result.parts.mantisa == 0ll) { /* fix zero */ |
result.parts.exp = 0ll; |
return result; |
} |
mant = result.parts.mantisa; |
while (!(mant & (0x10000000000000ll))) { |
mant <<= 1; |
--result.parts.exp; |
}; |
result.parts.mantisa = mant; |
}; |
return result; |
}; |
float32 convertFloat64ToFloat32(float64 a) |
{ |
float32 result; |
__s32 exp; |
__u64 mant; |
result.parts.sign = a.parts.sign; |
if (isFloat64NaN(a)) { |
result.parts.exp = 0xFF; |
if (isFloat64SigNaN(a)) { |
result.parts.mantisa = 0x800000; /* set first bit of mantisa nonzero */ |
return result; |
} |
result.parts.mantisa = 0x1; /* mantisa nonzero but its first bit is zero */ |
return result; |
}; |
if (isFloat64Infinity(a)) { |
result.parts.mantisa = 0; |
result.parts.exp = 0xFF; |
return result; |
}; |
exp = (int)a.parts.exp - FLOAT64_BIAS + FLOAT32_BIAS; |
if (exp >= 0xFF) { |
/*FIXME: overflow*/ |
result.parts.mantisa = 0; |
result.parts.exp = 0xFF; |
return result; |
} else if (exp <= 0 ) { |
/* underflow or denormalized */ |
result.parts.exp = 0; |
exp *= -1; |
if (exp > FLOAT32_MANTISA_SIZE ) { |
/* FIXME: underflow */ |
result.parts.mantisa = 0; |
return result; |
}; |
/* denormalized */ |
mant = result.parts.mantisa >> 1; |
mant |= 0x10000000000000ll; /* denormalize and set hidden bit */ |
while (exp > 0) { |
--exp; |
mant >>= 1; |
}; |
result.parts.mantisa = mant; |
return result; |
}; |
result.parts.exp = exp; |
result.parts.mantisa = a.parts.mantisa >> (FLOAT64_MANTISA_SIZE - FLOAT32_MANTISA_SIZE); |
return result; |
}; |
//uspace/trunk/softfloat/generic/comparison.c |
---|
34,21 → 34,41 |
return ((f.parts.exp==0xFF)&&(f.parts.mantisa)); |
}; |
inline int isFloat64NaN(float64 d) |
{ /* NaN : exp = 0x7ff and nonzero mantisa */ |
return ((d.parts.exp==0x7FF)&&(d.parts.mantisa)); |
}; |
inline int isFloat32SigNaN(float32 f) |
{ /* SigNaN : exp = 0xff mantisa = 1xxxxx..x (binary), where at least one x is nonzero */ |
return ((f.parts.exp==0xFF)&&(f.parts.mantisa>0x400000)); |
}; |
inline int isFloat64SigNaN(float64 d) |
{ /* SigNaN : exp = 0x7ff mantisa = 1xxxxx..x (binary), where at least one x is nonzero */ |
return ((d.parts.exp==0x7FF)&&(d.parts.mantisa>0x8000000000000ll)); |
}; |
inline int isFloat32Infinity(float32 f) |
{ |
return ((f.parts.exp==0xFF)&&(f.parts.mantisa==0x0)); |
}; |
inline int isFloat64Infinity(float64 d) |
{ |
return ((d.parts.exp==0x7FF)&&(d.parts.mantisa==0x0)); |
}; |
inline int isFloat32Zero(float32 f) |
{ |
return (((f.binary) & 0x7FFFFFFF) == 0); |
} |
inline int isFloat64Zero(float64 d) |
{ |
return (((d.binary) & 0x7FFFFFFFFFFFFFFFll) == 0); |
} |
/** |
* @return 1, if both floats are equal - but NaNs are not recognized |
*/ |
100,3 → 120,4 |
} |