123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- #include <sys/cdefs.h>
- __FBSDID("$FreeBSD$");
- #include <float.h>
- #include "math.h"
- #include "math_private.h"
- #include "k_log.h"
- static const double
- two54 = 1.80143985094819840000e+16,
- ivln2hi = 1.44269504072144627571e+00,
- ivln2lo = 1.67517131648865118353e-10;
- static const double zero = 0.0;
- static volatile double vzero = 0.0;
- double
- __ieee754_log2(double x)
- {
- double f,hfsq,hi,lo,r,val_hi,val_lo,w,y;
- int32_t i,k,hx;
- u_int32_t lx;
- EXTRACT_WORDS(hx,lx,x);
- k=0;
- if (hx < 0x00100000) {
- if (((hx&0x7fffffff)|lx)==0)
- return -two54/vzero;
- if (hx<0) return (x-x)/zero;
- k -= 54; x *= two54;
- GET_HIGH_WORD(hx,x);
- }
- if (hx >= 0x7ff00000) return x+x;
- if (hx == 0x3ff00000 && lx == 0)
- return zero;
- k += (hx>>20)-1023;
- hx &= 0x000fffff;
- i = (hx+0x95f64)&0x100000;
- SET_HIGH_WORD(x,hx|(i^0x3ff00000));
- k += (i>>20);
- y = (double)k;
- f = x - 1.0;
- hfsq = 0.5*f*f;
- r = k_log1p(f);
-
- hi = f - hfsq;
- SET_LOW_WORD(hi,0);
- lo = (f - hi) - hfsq + r;
- val_hi = hi*ivln2hi;
- val_lo = (lo+hi)*ivln2lo + lo*ivln2hi;
-
- w = y + val_hi;
- val_lo += (y - w) + val_hi;
- val_hi = w;
- return val_lo + val_hi;
- }
- #if (LDBL_MANT_DIG == 53)
- __weak_reference(log2, log2l);
- #endif
|