math: cosmetic cleanup (use explicit union instead of fshape and dshape)
This commit is contained in:
parent
63b9cc7773
commit
8dba548628
11 changed files with 140 additions and 166 deletions
|
|
@ -1,10 +1,11 @@
|
|||
#include "libm.h"
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
|
||||
int __fpclassify(double x)
|
||||
{
|
||||
union dshape u = { x };
|
||||
int e = u.bits>>52 & 0x7ff;
|
||||
if (!e) return u.bits<<1 ? FP_SUBNORMAL : FP_ZERO;
|
||||
if (e==0x7ff) return u.bits<<12 ? FP_NAN : FP_INFINITE;
|
||||
union {double f; uint64_t i;} u = {x};
|
||||
int e = u.i>>52 & 0x7ff;
|
||||
if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO;
|
||||
if (e==0x7ff) return u.i<<12 ? FP_NAN : FP_INFINITE;
|
||||
return FP_NORMAL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
#include "libm.h"
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
|
||||
int __fpclassifyf(float x)
|
||||
{
|
||||
union fshape u = { x };
|
||||
int e = u.bits>>23 & 0xff;
|
||||
if (!e) return u.bits<<1 ? FP_SUBNORMAL : FP_ZERO;
|
||||
if (e==0xff) return u.bits<<9 ? FP_NAN : FP_INFINITE;
|
||||
union {float f; uint32_t i;} u = {x};
|
||||
int e = u.i>>23 & 0xff;
|
||||
if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO;
|
||||
if (e==0xff) return u.i<<9 ? FP_NAN : FP_INFINITE;
|
||||
return FP_NORMAL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,8 @@
|
|||
#include "libm.h"
|
||||
|
||||
double copysign(double x, double y) {
|
||||
union dshape ux, uy;
|
||||
|
||||
ux.value = x;
|
||||
uy.value = y;
|
||||
ux.bits &= (uint64_t)-1>>1;
|
||||
ux.bits |= uy.bits & (uint64_t)1<<63;
|
||||
return ux.value;
|
||||
union {double f; uint64_t i;} ux={x}, uy={y};
|
||||
ux.i &= -1ULL/2;
|
||||
ux.i |= uy.i & 1ULL<<63;
|
||||
return ux.f;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
#include "libm.h"
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
|
||||
float copysignf(float x, float y) {
|
||||
union fshape ux, uy;
|
||||
|
||||
ux.value = x;
|
||||
uy.value = y;
|
||||
ux.bits &= (uint32_t)-1>>1;
|
||||
ux.bits |= uy.bits & (uint32_t)1<<31;
|
||||
return ux.value;
|
||||
float copysignf(float x, float y)
|
||||
{
|
||||
union {float f; uint32_t i;} ux={x}, uy={y};
|
||||
ux.i &= 0x7fffffff;
|
||||
ux.i |= uy.i & 0x80000000;
|
||||
return ux.f;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
#include "libm.h"
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
|
||||
double fabs(double x)
|
||||
{
|
||||
union dshape u;
|
||||
|
||||
u.value = x;
|
||||
u.bits &= (uint64_t)-1 / 2;
|
||||
return u.value;
|
||||
union {double f; uint64_t i;} u = {x};
|
||||
u.i &= -1ULL/2;
|
||||
return u.f;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
#include "libm.h"
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
|
||||
float fabsf(float x)
|
||||
{
|
||||
union fshape u;
|
||||
|
||||
u.value = x;
|
||||
u.bits &= (uint32_t)-1 / 2;
|
||||
return u.value;
|
||||
union {float f; uint32_t i;} u = {x};
|
||||
u.i &= 0x7fffffff;
|
||||
return u.f;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,35 +1,31 @@
|
|||
#include "libm.h"
|
||||
|
||||
#define SIGN ((uint64_t)1<<63)
|
||||
|
||||
double nextafter(double x, double y)
|
||||
{
|
||||
union dshape ux, uy;
|
||||
union {double f; uint64_t i;} ux={x}, uy={y};
|
||||
uint64_t ax, ay;
|
||||
int e;
|
||||
|
||||
if (isnan(x) || isnan(y))
|
||||
return x + y;
|
||||
ux.value = x;
|
||||
uy.value = y;
|
||||
if (ux.bits == uy.bits)
|
||||
if (ux.i == uy.i)
|
||||
return y;
|
||||
ax = ux.bits & ~SIGN;
|
||||
ay = uy.bits & ~SIGN;
|
||||
ax = ux.i & -1ULL/2;
|
||||
ay = uy.i & -1ULL/2;
|
||||
if (ax == 0) {
|
||||
if (ay == 0)
|
||||
return y;
|
||||
ux.bits = (uy.bits & SIGN) | 1;
|
||||
} else if (ax > ay || ((ux.bits ^ uy.bits) & SIGN))
|
||||
ux.bits--;
|
||||
ux.i = (uy.i & 1ULL<<63) | 1;
|
||||
} else if (ax > ay || ((ux.i ^ uy.i) & 1ULL<<63))
|
||||
ux.i--;
|
||||
else
|
||||
ux.bits++;
|
||||
e = ux.bits >> 52 & 0x7ff;
|
||||
/* raise overflow if ux.value is infinite and x is finite */
|
||||
ux.i++;
|
||||
e = ux.i >> 52 & 0x7ff;
|
||||
/* raise overflow if ux.f is infinite and x is finite */
|
||||
if (e == 0x7ff)
|
||||
FORCE_EVAL(x+x);
|
||||
/* raise underflow if ux.value is subnormal or zero */
|
||||
/* raise underflow if ux.f is subnormal or zero */
|
||||
if (e == 0)
|
||||
FORCE_EVAL(x*x + ux.value*ux.value);
|
||||
return ux.value;
|
||||
FORCE_EVAL(x*x + ux.f*ux.f);
|
||||
return ux.f;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,34 +1,30 @@
|
|||
#include "libm.h"
|
||||
|
||||
#define SIGN 0x80000000
|
||||
|
||||
float nextafterf(float x, float y)
|
||||
{
|
||||
union fshape ux, uy;
|
||||
union {float f; uint32_t i;} ux={x}, uy={y};
|
||||
uint32_t ax, ay, e;
|
||||
|
||||
if (isnan(x) || isnan(y))
|
||||
return x + y;
|
||||
ux.value = x;
|
||||
uy.value = y;
|
||||
if (ux.bits == uy.bits)
|
||||
if (ux.i == uy.i)
|
||||
return y;
|
||||
ax = ux.bits & ~SIGN;
|
||||
ay = uy.bits & ~SIGN;
|
||||
ax = ux.i & 0x7fffffff;
|
||||
ay = uy.i & 0x7fffffff;
|
||||
if (ax == 0) {
|
||||
if (ay == 0)
|
||||
return y;
|
||||
ux.bits = (uy.bits & SIGN) | 1;
|
||||
} else if (ax > ay || ((ux.bits ^ uy.bits) & SIGN))
|
||||
ux.bits--;
|
||||
ux.i = (uy.i & 0x80000000) | 1;
|
||||
} else if (ax > ay || ((ux.i ^ uy.i) & 0x80000000))
|
||||
ux.i--;
|
||||
else
|
||||
ux.bits++;
|
||||
e = ux.bits & 0x7f800000;
|
||||
/* raise overflow if ux.value is infinite and x is finite */
|
||||
ux.i++;
|
||||
e = ux.i & 0x7f800000;
|
||||
/* raise overflow if ux.f is infinite and x is finite */
|
||||
if (e == 0x7f800000)
|
||||
FORCE_EVAL(x+x);
|
||||
/* raise underflow if ux.value is subnormal or zero */
|
||||
/* raise underflow if ux.f is subnormal or zero */
|
||||
if (e == 0)
|
||||
FORCE_EVAL(x*x + ux.value*ux.value);
|
||||
return ux.value;
|
||||
FORCE_EVAL(x*x + ux.f*ux.f);
|
||||
return ux.f;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,40 +6,37 @@ double nexttoward(double x, long double y)
|
|||
return nextafter(x, y);
|
||||
}
|
||||
#else
|
||||
#define SIGN ((uint64_t)1<<63)
|
||||
|
||||
double nexttoward(double x, long double y)
|
||||
{
|
||||
union dshape ux;
|
||||
union {double f; uint64_t i;} ux = {x};
|
||||
int e;
|
||||
|
||||
if (isnan(x) || isnan(y))
|
||||
return x + y;
|
||||
if (x == y)
|
||||
return y;
|
||||
ux.value = x;
|
||||
if (x == 0) {
|
||||
ux.bits = 1;
|
||||
ux.i = 1;
|
||||
if (signbit(y))
|
||||
ux.bits |= SIGN;
|
||||
ux.i |= 1ULL<<63;
|
||||
} else if (x < y) {
|
||||
if (signbit(x))
|
||||
ux.bits--;
|
||||
ux.i--;
|
||||
else
|
||||
ux.bits++;
|
||||
ux.i++;
|
||||
} else {
|
||||
if (signbit(x))
|
||||
ux.bits++;
|
||||
ux.i++;
|
||||
else
|
||||
ux.bits--;
|
||||
ux.i--;
|
||||
}
|
||||
e = ux.bits>>52 & 0x7ff;
|
||||
/* raise overflow if ux.value is infinite and x is finite */
|
||||
e = ux.i>>52 & 0x7ff;
|
||||
/* raise overflow if ux.f is infinite and x is finite */
|
||||
if (e == 0x7ff)
|
||||
FORCE_EVAL(x+x);
|
||||
/* raise underflow if ux.value is subnormal or zero */
|
||||
/* raise underflow if ux.f is subnormal or zero */
|
||||
if (e == 0)
|
||||
FORCE_EVAL(x*x + ux.value*ux.value);
|
||||
return ux.value;
|
||||
FORCE_EVAL(x*x + ux.f*ux.f);
|
||||
return ux.f;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -2,35 +2,34 @@
|
|||
|
||||
float nexttowardf(float x, long double y)
|
||||
{
|
||||
union fshape ux;
|
||||
union {float f; uint32_t i;} ux = {x};
|
||||
uint32_t e;
|
||||
|
||||
if (isnan(x) || isnan(y))
|
||||
return x + y;
|
||||
if (x == y)
|
||||
return y;
|
||||
ux.value = x;
|
||||
if (x == 0) {
|
||||
ux.bits = 1;
|
||||
ux.i = 1;
|
||||
if (signbit(y))
|
||||
ux.bits |= 0x80000000;
|
||||
ux.i |= 0x80000000;
|
||||
} else if (x < y) {
|
||||
if (signbit(x))
|
||||
ux.bits--;
|
||||
ux.i--;
|
||||
else
|
||||
ux.bits++;
|
||||
ux.i++;
|
||||
} else {
|
||||
if (signbit(x))
|
||||
ux.bits++;
|
||||
ux.i++;
|
||||
else
|
||||
ux.bits--;
|
||||
ux.i--;
|
||||
}
|
||||
e = ux.bits & 0x7f800000;
|
||||
/* raise overflow if ux.value is infinite and x is finite */
|
||||
e = ux.i & 0x7f800000;
|
||||
/* raise overflow if ux.f is infinite and x is finite */
|
||||
if (e == 0x7f800000)
|
||||
FORCE_EVAL(x+x);
|
||||
/* raise underflow if ux.value is subnormal or zero */
|
||||
/* raise underflow if ux.f is subnormal or zero */
|
||||
if (e == 0)
|
||||
FORCE_EVAL(x*x + ux.value*ux.value);
|
||||
return ux.value;
|
||||
FORCE_EVAL(x*x + ux.f*ux.f);
|
||||
return ux.f;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue