mirror of https://git.musl-libc.org/git/musl
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) |
int __fpclassify(double x) |
||||
{ |
{ |
||||
union dshape u = { x }; |
union {double f; uint64_t i;} u = {x}; |
||||
int e = u.bits>>52 & 0x7ff; |
int e = u.i>>52 & 0x7ff; |
||||
if (!e) return u.bits<<1 ? FP_SUBNORMAL : FP_ZERO; |
if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO; |
||||
if (e==0x7ff) return u.bits<<12 ? FP_NAN : FP_INFINITE; |
if (e==0x7ff) return u.i<<12 ? FP_NAN : FP_INFINITE; |
||||
return FP_NORMAL; |
return FP_NORMAL; |
||||
} |
} |
||||
|
|||||
@ -1,10 +1,11 @@ |
|||||
#include "libm.h" |
#include <math.h> |
||||
|
#include <stdint.h> |
||||
|
|
||||
int __fpclassifyf(float x) |
int __fpclassifyf(float x) |
||||
{ |
{ |
||||
union fshape u = { x }; |
union {float f; uint32_t i;} u = {x}; |
||||
int e = u.bits>>23 & 0xff; |
int e = u.i>>23 & 0xff; |
||||
if (!e) return u.bits<<1 ? FP_SUBNORMAL : FP_ZERO; |
if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO; |
||||
if (e==0xff) return u.bits<<9 ? FP_NAN : FP_INFINITE; |
if (e==0xff) return u.i<<9 ? FP_NAN : FP_INFINITE; |
||||
return FP_NORMAL; |
return FP_NORMAL; |
||||
} |
} |
||||
|
|||||
@ -1,11 +1,8 @@ |
|||||
#include "libm.h" |
#include "libm.h" |
||||
|
|
||||
double copysign(double x, double y) { |
double copysign(double x, double y) { |
||||
union dshape ux, uy; |
union {double f; uint64_t i;} ux={x}, uy={y}; |
||||
|
ux.i &= -1ULL/2; |
||||
ux.value = x; |
ux.i |= uy.i & 1ULL<<63; |
||||
uy.value = y; |
return ux.f; |
||||
ux.bits &= (uint64_t)-1>>1; |
|
||||
ux.bits |= uy.bits & (uint64_t)1<<63; |
|
||||
return ux.value; |
|
||||
} |
} |
||||
|
|||||
@ -1,11 +1,10 @@ |
|||||
#include "libm.h" |
#include <math.h> |
||||
|
#include <stdint.h> |
||||
|
|
||||
float copysignf(float x, float y) { |
float copysignf(float x, float y) |
||||
union fshape ux, uy; |
{ |
||||
|
union {float f; uint32_t i;} ux={x}, uy={y}; |
||||
ux.value = x; |
ux.i &= 0x7fffffff; |
||||
uy.value = y; |
ux.i |= uy.i & 0x80000000; |
||||
ux.bits &= (uint32_t)-1>>1; |
return ux.f; |
||||
ux.bits |= uy.bits & (uint32_t)1<<31; |
|
||||
return ux.value; |
|
||||
} |
} |
||||
|
|||||
@ -1,10 +1,9 @@ |
|||||
#include "libm.h" |
#include <math.h> |
||||
|
#include <stdint.h> |
||||
|
|
||||
double fabs(double x) |
double fabs(double x) |
||||
{ |
{ |
||||
union dshape u; |
union {double f; uint64_t i;} u = {x}; |
||||
|
u.i &= -1ULL/2; |
||||
u.value = x; |
return u.f; |
||||
u.bits &= (uint64_t)-1 / 2; |
|
||||
return u.value; |
|
||||
} |
} |
||||
|
|||||
@ -1,10 +1,9 @@ |
|||||
#include "libm.h" |
#include <math.h> |
||||
|
#include <stdint.h> |
||||
|
|
||||
float fabsf(float x) |
float fabsf(float x) |
||||
{ |
{ |
||||
union fshape u; |
union {float f; uint32_t i;} u = {x}; |
||||
|
u.i &= 0x7fffffff; |
||||
u.value = x; |
return u.f; |
||||
u.bits &= (uint32_t)-1 / 2; |
|
||||
return u.value; |
|
||||
} |
} |
||||
|
|||||
@ -1,35 +1,31 @@ |
|||||
#include "libm.h" |
#include "libm.h" |
||||
|
|
||||
#define SIGN ((uint64_t)1<<63) |
|
||||
|
|
||||
double nextafter(double x, double y) |
double nextafter(double x, double y) |
||||
{ |
{ |
||||
union dshape ux, uy; |
union {double f; uint64_t i;} ux={x}, uy={y}; |
||||
uint64_t ax, ay; |
uint64_t ax, ay; |
||||
int e; |
int e; |
||||
|
|
||||
if (isnan(x) || isnan(y)) |
if (isnan(x) || isnan(y)) |
||||
return x + y; |
return x + y; |
||||
ux.value = x; |
if (ux.i == uy.i) |
||||
uy.value = y; |
|
||||
if (ux.bits == uy.bits) |
|
||||
return y; |
return y; |
||||
ax = ux.bits & ~SIGN; |
ax = ux.i & -1ULL/2; |
||||
ay = uy.bits & ~SIGN; |
ay = uy.i & -1ULL/2; |
||||
if (ax == 0) { |
if (ax == 0) { |
||||
if (ay == 0) |
if (ay == 0) |
||||
return y; |
return y; |
||||
ux.bits = (uy.bits & SIGN) | 1; |
ux.i = (uy.i & 1ULL<<63) | 1; |
||||
} else if (ax > ay || ((ux.bits ^ uy.bits) & SIGN)) |
} else if (ax > ay || ((ux.i ^ uy.i) & 1ULL<<63)) |
||||
ux.bits--; |
ux.i--; |
||||
else |
else |
||||
ux.bits++; |
ux.i++; |
||||
e = ux.bits >> 52 & 0x7ff; |
e = ux.i >> 52 & 0x7ff; |
||||
/* raise overflow if ux.value is infinite and x is finite */ |
/* raise overflow if ux.f is infinite and x is finite */ |
||||
if (e == 0x7ff) |
if (e == 0x7ff) |
||||
FORCE_EVAL(x+x); |
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) |
if (e == 0) |
||||
FORCE_EVAL(x*x + ux.value*ux.value); |
FORCE_EVAL(x*x + ux.f*ux.f); |
||||
return ux.value; |
return ux.f; |
||||
} |
} |
||||
|
|||||
@ -1,34 +1,30 @@ |
|||||
#include "libm.h" |
#include "libm.h" |
||||
|
|
||||
#define SIGN 0x80000000 |
|
||||
|
|
||||
float nextafterf(float x, float y) |
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; |
uint32_t ax, ay, e; |
||||
|
|
||||
if (isnan(x) || isnan(y)) |
if (isnan(x) || isnan(y)) |
||||
return x + y; |
return x + y; |
||||
ux.value = x; |
if (ux.i == uy.i) |
||||
uy.value = y; |
|
||||
if (ux.bits == uy.bits) |
|
||||
return y; |
return y; |
||||
ax = ux.bits & ~SIGN; |
ax = ux.i & 0x7fffffff; |
||||
ay = uy.bits & ~SIGN; |
ay = uy.i & 0x7fffffff; |
||||
if (ax == 0) { |
if (ax == 0) { |
||||
if (ay == 0) |
if (ay == 0) |
||||
return y; |
return y; |
||||
ux.bits = (uy.bits & SIGN) | 1; |
ux.i = (uy.i & 0x80000000) | 1; |
||||
} else if (ax > ay || ((ux.bits ^ uy.bits) & SIGN)) |
} else if (ax > ay || ((ux.i ^ uy.i) & 0x80000000)) |
||||
ux.bits--; |
ux.i--; |
||||
else |
else |
||||
ux.bits++; |
ux.i++; |
||||
e = ux.bits & 0x7f800000; |
e = ux.i & 0x7f800000; |
||||
/* raise overflow if ux.value is infinite and x is finite */ |
/* raise overflow if ux.f is infinite and x is finite */ |
||||
if (e == 0x7f800000) |
if (e == 0x7f800000) |
||||
FORCE_EVAL(x+x); |
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) |
if (e == 0) |
||||
FORCE_EVAL(x*x + ux.value*ux.value); |
FORCE_EVAL(x*x + ux.f*ux.f); |
||||
return ux.value; |
return ux.f; |
||||
} |
} |
||||
|
|||||
Loading…
Reference in new issue