#include #include static const uint16 tab[128] = { 0xb451,0xb2f0,0xb196,0xb044,0xaef9,0xadb6,0xac79,0xab43, 0xaa14,0xa8eb,0xa7c8,0xa6aa,0xa592,0xa480,0xa373,0xa26b, 0xa168,0xa06a,0x9f70,0x9e7b,0x9d8a,0x9c9d,0x9bb5,0x9ad1, 0x99f0,0x9913,0x983a,0x9765,0x9693,0x95c4,0x94f8,0x9430, 0x936b,0x92a9,0x91ea,0x912e,0x9075,0x8fbe,0x8f0a,0x8e59, 0x8daa,0x8cfe,0x8c54,0x8bac,0x8b07,0x8a64,0x89c4,0x8925, 0x8889,0x87ee,0x8756,0x86c0,0x862b,0x8599,0x8508,0x8479, 0x83ec,0x8361,0x82d8,0x8250,0x81c9,0x8145,0x80c2,0x8040, 0xff02,0xfd0e,0xfb25,0xf947,0xf773,0xf5aa,0xf3ea,0xf234, 0xf087,0xeee3,0xed47,0xebb3,0xea27,0xe8a3,0xe727,0xe5b2, 0xe443,0xe2dc,0xe17a,0xe020,0xdecb,0xdd7d,0xdc34,0xdaf1, 0xd9b3,0xd87b,0xd748,0xd61a,0xd4f1,0xd3cd,0xd2ad,0xd192, 0xd07b,0xcf69,0xce5b,0xcd51,0xcc4a,0xcb48,0xca4a,0xc94f, 0xc858,0xc764,0xc674,0xc587,0xc49d,0xc3b7,0xc2d4,0xc1f4, 0xc116,0xc03c,0xbf65,0xbe90,0xbdbe,0xbcef,0xbc23,0xbb59, 0xba91,0xb9cc,0xb90a,0xb84a,0xb78c,0xb6d0,0xb617,0xb560, }; static inline uint32 mul32(uint32 a, uint32 b) { return (uint64)a*b >> 32; } float math·sqrtf(float x) { uint32 ix, m, m1, m0, even, ey; union{float f; uint32 i;} phi; phi.f=x, ix=phi.i; if(ix - 0x00800000 >= 0x7f800000 - 0x00800000){ /* x < 0x1p-126 or inf or nan. */ if(ix * 2 == 0) return x; if(ix == 0x7f800000) return x; if(ix > 0x7f800000) return (x-x)/(x-x); /* x is subnormal, normalize it. */ phi.f=x * 0x1p23f, ix=phi.i; ix -= 23 << 23; } /* x = 4^e m; with int e and m in [1, 4). */ even = ix & 0x00800000; m1 = (ix << 8) | 0x80000000; m0 = (ix << 7) & 0x7fffffff; m = even ? m0 : m1; /* 2^e is the exponent part of the return value. */ ey = ix >> 1; ey += 0x3f800000 >> 1; ey &= 0x7f800000; /* compute r ~ 1/sqrt(m), s ~ sqrt(m) with 2 goldschmidt iterations. */ static const uint32 three = 0xc0000000; uint32 r, s, d, u, i; i = (ix >> 17) % 128; r = (uint32)tab[i] << 16; /* |r*sqrt(m) - 1| < 0x1p-8 */ s = mul32(m, r); /* |s/sqrt(m) - 1| < 0x1p-8 */ d = mul32(s, r); u = three - d; r = mul32(r, u) << 1; /* |r*sqrt(m) - 1| < 0x1.7bp-16 */ s = mul32(s, u) << 1; /* |s/sqrt(m) - 1| < 0x1.7bp-16 */ d = mul32(s, r); u = three - d; s = mul32(s, u); /* -0x1.03p-28 < s/sqrt(m) - 1 < 0x1.fp-31 */ s = (s - 1)>>6; /* s < sqrt(m) < s + 0x1.08p-23 */ /* compute nearest rounded result. */ uint32 d0, d1, d2; float y, t; d0 = (m << 16) - s*s; d1 = s - d0; d2 = d1 + s + 1; s += d1 >> 31; s &= 0x007fffff; s |= ey; phi.i = s, y = phi.f; /* handle rounding and inexact exception. */ uint32 tiny = (d2==0) ? 0 : 0x01000000; tiny |= (d1^d2) & 0x80000000; phi.i=tiny, t=phi.f; y = y + t; return y; }