| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906 |
- /******************************************************************************
- 版权所有:
- 文件名称: rt_clib.c
- 文件版本: 01.01
- 创建作者: sunxi
- 创建日期: 2020-06-18
- 功能说明: 实时微系统标准C库接口。
- 其它说明:
- 修改记录:
- */
- /*------------------------------- 头文件 --------------------------------------
- */
- #include "rt_clib.h"
- #include "rt.h"
- /*------------------------------- 宏定义 --------------------------------------
- */
- /*------------------------------ 类型结构 -------------------------------------
- */
- /*------------------------------ 全局变量 -------------------------------------
- */
- /*------------------------------ 函数声明 -------------------------------------
- */
- /*------------------------------ 外部函数 -------------------------------------
- 外部函数供其它实体文件引用,必须仔细检查传入参数的合法性.
- */
- // noted by sunxi: 20220415 好像没有用,屏蔽掉
- /*
- //64位除法
- static inline u64 div64_u64(u64 dividend, u64 divisor)
- {
- return dividend / divisor;
- }
- uint32_t long __udivdi3(uint32_t long num,uint32_t long den)
- {
- return div64_u64(num,den);
- }
- */
- #if 0
- //abort,函数打印消息后返回,并不会终止程序运行。
- void abort(void)
- {
- rt_printf("!!!call abort!!!\r\n");
- }
- #endif
- #if 0
- //http://www.opensource.apple.com/source/xnu/xnu-792.13.8/libsa/bsearch.c
- void * bsearch(const void *key, const void *base0, int nmemb, int size, int (*compar)(const void *, const void *))
- {
- register const char *base = base0;
- register int lim;
- register int cmp;
- register const void *p;
- for (lim = nmemb; lim != 0; lim >>= 1) {
- p = base + (lim >> 1) * size;
- cmp = (*compar)(key, p);
- if (cmp == 0)
- return ((void *)p);
- if (cmp > 0) { /* key > p: move right */
- base = (char *)p + size;
- lim--;
- } /* else move left */
- }
- return (0);
- }
- #endif
- // http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/bsd/libkern/strtol.c
- static inline int
- _isupper(char c)
- {
- return (c >= 'A' && c <= 'Z');
- }
- static inline int
- _isalpha(char c)
- {
- return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'));
- }
- static inline int
- _isspace(char c)
- {
- return (c == ' ' || c == '\t' || c == '\n' || c == '\12');
- }
- static inline int
- _isdigit(char c)
- {
- return (c >= '0' && c <= '9');
- }
- /*
- * Convert a string to a long integer.
- *
- * Ignores `locale' stuff. Assumes that the upper and lower case
- * alphabets and digits are each contiguous.
- */
- long strtol(const char *nptr, char **endptr, int base)
- {
- register const char *s = nptr;
- register unsigned long acc;
- register int c;
- register unsigned long cutoff;
- register int neg = 0, any, cutlim;
- /*
- * Skip white space and pick up leading +/- sign if any.
- * If base is 0, allow 0x for hex and 0 for octal, else
- * assume decimal; if base is already 16, allow 0x.
- */
- do
- {
- c = *s++;
- } while (_isspace(c));
- if (c == '-')
- {
- neg = 1;
- c = *s++;
- }
- else if (c == '+')
- c = *s++;
- if ((base == 0 || base == 16) &&
- c == '0' && (*s == 'x' || *s == 'X'))
- {
- c = s[1];
- s += 2;
- base = 16;
- }
- else if ((base == 0 || base == 2) &&
- c == '0' && (*s == 'b' || *s == 'B'))
- {
- c = s[1];
- s += 2;
- base = 2;
- }
- if (base == 0)
- base = c == '0' ? 8 : 10;
- /*
- * Compute the cutoff value between legal numbers and illegal
- * numbers. That is the largest legal value, divided by the
- * base. An input number that is greater than this value, if
- * followed by a legal input character, is too big. One that
- * is equal to this value may be valid or not; the limit
- * between valid and invalid numbers is then based on the last
- * digit. For instance, if the range for longs is
- * [-2147483648..2147483647] and the input base is 10,
- * cutoff will be set to 214748364 and cutlim to either
- * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
- * a value > 214748364, or equal but the next digit is > 7 (or 8),
- * the number is too big, and we will return a range error.
- *
- * Set any if any `digits' consumed; make it negative to indicate
- * overflow.
- */
- cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX;
- cutlim = cutoff % (unsigned long)base;
- cutoff /= (unsigned long)base;
- for (acc = 0, any = 0;; c = *s++)
- {
- if (_isdigit(c))
- c -= '0';
- else if (_isalpha(c))
- c -= _isupper(c) ? 'A' - 10 : 'a' - 10;
- else
- break;
- if (c >= base)
- break;
- if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
- any = -1;
- else
- {
- any = 1;
- acc *= base;
- acc += c;
- }
- }
- if (any < 0)
- {
- acc = neg ? LONG_MIN : LONG_MAX;
- // errno = ERANGE;
- }
- else if (neg)
- acc = -acc;
- if (endptr != 0)
- *endptr = (char *)(any ? s - 1 : nptr);
- return (acc);
- }
- /*
- * Convert a string to an unsigned long integer.
- *
- * Ignores `locale' stuff. Assumes that the upper and lower case
- * alphabets and digits are each contiguous.
- */
- unsigned long strtoul(const char *nptr, char **endptr, int base)
- {
- register const char *s = nptr;
- register unsigned long acc;
- register int c;
- register unsigned long cutoff;
- register int neg = 0, any, cutlim;
- /*
- * See strtol for comments as to the logic used.
- */
- do
- {
- c = *s++;
- } while (_isspace(c));
- if (c == '-')
- {
- neg = 1;
- c = *s++;
- }
- else if (c == '+')
- c = *s++;
- if ((base == 0 || base == 16) &&
- c == '0' && (*s == 'x' || *s == 'X'))
- {
- c = s[1];
- s += 2;
- base = 16;
- }
- else if ((base == 0 || base == 2) &&
- c == '0' && (*s == 'b' || *s == 'B'))
- {
- c = s[1];
- s += 2;
- base = 2;
- }
- if (base == 0)
- base = c == '0' ? 8 : 10;
- cutoff = (unsigned long)ULONG_MAX / (unsigned long)base;
- cutlim = (unsigned long)ULONG_MAX % (unsigned long)base;
- for (acc = 0, any = 0;; c = *s++)
- {
- if (_isdigit(c))
- c -= '0';
- else if (_isalpha(c))
- c -= _isupper(c) ? 'A' - 10 : 'a' - 10;
- else
- break;
- if (c >= base)
- break;
- if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
- any = -1;
- else
- {
- any = 1;
- acc *= base;
- acc += c;
- }
- }
- if (any < 0)
- {
- acc = ULONG_MAX;
- // errno = ERANGE;
- }
- else if (neg)
- acc = -acc;
- if (endptr != 0)
- *endptr = (char *)(any ? s - 1 : nptr);
- return (acc);
- }
- /* MSL
- * Copyright 1995-2007 Freescale Corporation. All rights reserved.
- *
- * $Date: 2009/11/05 19:15:41 $
- * $Revision: 1.2 $
- */
- /*
- Author: Matthew D. Fassiotto
- Date: first written 4/15/99
- Purpose: non-optimal single precision version of standard sqrt functions
- Assumptions: --IEEE 754 single precision float format
- *fp difference should never produce -0
- *casting a float to an int always truncates regardless of fp rounding mode.
- *the type _INT32 is 32 bits(i.e. sizeof(_INT32)=sizeof(float)
- Note: need to eliminate two divisions in Newton iteration
- */
- // #include <math.h>
- // #include <errno.h>
- static int sqrt_guess[] = {0x3F35B99E, 0x3F366D96, 0x3F3720DD, 0x3F37D375, 0x3F388560, 0x3F3936A1, 0x3F39E738,
- 0x3F3A9728, 0x3F3B4673, 0x3F3BF51B, 0x3F3CA321, 0x3F3D5087, 0x3F3DFD4E, 0x3F3EA979, 0x3F3F5509, 0x3F400000,
- 0x3F40AA5F, 0x3F415428, 0x3F41FD5C, 0x3F42A5FE, 0x3F434E0D, 0x3F43F58D, 0x3F449C7E, 0x3F4542E1, 0x3F45E8B9,
- 0x3F468E06, 0x3F4732CA, 0x3F47D706, 0x3F487ABC, 0x3F491DEC, 0x3F49C098, 0x3F4A62C2, 0x3F4B046A, 0x3F4BA592,
- 0x3F4C463A, 0x3F4CE665, 0x3F4D8613, 0x3F4E2545, 0x3F4EC3FC, 0x3F4F623A, 0x3F500000, 0x3F509D4E, 0x3F513A26,
- 0x3F51D689, 0x3F527278, 0x3F530DF3, 0x3F53A8FD, 0x3F544395, 0x3F54DDBC, 0x3F557775, 0x3F5610BF, 0x3F56A99B,
- 0x3F57420B, 0x3F57DA10, 0x3F5871A9, 0x3F5908D9, 0x3F599FA0, 0x3F5A35FE, 0x3F5ACBF5, 0x3F5B6186, 0x3F5BF6B1,
- 0x3F5C8B77, 0x3F5D1FD9, 0x3F5DB3D7, 0x3F5E4773, 0x3F5EDAAE, 0x3F5F6D87, 0x3F600000, 0x3F609219, 0x3F6123D4,
- 0x3F61B531, 0x3F624630, 0x3F62D6D3, 0x3F636719, 0x3F63F704, 0x3F648695, 0x3F6515CC, 0x3F65A4A9, 0x3F66332E,
- 0x3F66C15A, 0x3F674F2F, 0x3F67DCAE, 0x3F6869D6, 0x3F68F6A9, 0x3F698327, 0x3F6A0F50, 0x3F6A9B26, 0x3F6B26A9,
- 0x3F6BB1D9, 0x3F6C3CB7, 0x3F6CC744, 0x3F6D517F, 0x3F6DDB6B, 0x3F6E6507, 0x3F6EEE53, 0x3F6F7751, 0x3F700000,
- 0x3F708862, 0x3F711076, 0x3F71983E, 0x3F721FBA, 0x3F72A6EA, 0x3F732DCF, 0x3F73B46A, 0x3F743ABA, 0x3F74C0C0,
- 0x3F75467E, 0x3F75CBF2, 0x3F76511E, 0x3F76D603, 0x3F775AA0, 0x3F77DEF6, 0x3F786305, 0x3F78E6CE, 0x3F796A52,
- 0x3F79ED91, 0x3F7A708B, 0x3F7AF340, 0x3F7B75B1, 0x3F7BF7DF, 0x3F7C79CA, 0x3F7CFB72, 0x3F7D7CD8, 0x3F7DFDFC,
- 0x3F7E7EDE, 0x3F7EFF7F, 0x3F7F7FE0, 0x3F800000, 0x3F803FF0};
- static int sqrt_guess2[] = {
- 0x3F00FF02,
- 0x3F017DC7,
- 0x3F01FC10,
- 0x3F0279DF,
- 0x3F02F734,
- 0x3F037413,
- 0x3F03F07B,
- 0x3F046C6F,
- 0x3F04E7EE,
- 0x3F0562FC,
- 0x3F05DD98,
- 0x3F0657C5,
- 0x3F06D182,
- 0x3F074AD3,
- 0x3F07C3B6,
- 0x3F083C2F,
- 0x3F08B43D,
- 0x3F092BE3,
- 0x3F09A320,
- 0x3F0A19F6,
- 0x3F0A9067,
- 0x3F0B0672,
- 0x3F0B7C1A,
- 0x3F0BF15E,
- 0x3F0C6641,
- 0x3F0CDAC3,
- 0x3F0D4EE4,
- 0x3F0DC2A7,
- 0x3F0E360B,
- 0x3F0EA912,
- 0x3F0F1BBD,
- 0x3F0F8E0C,
- 0x3F100000,
- 0x3F10719A,
- 0x3F10E2DC,
- 0x3F1153C4,
- 0x3F11C456,
- 0x3F123491,
- 0x3F12A476,
- 0x3F131406,
- 0x3F138341,
- 0x3F13F229,
- 0x3F1460BE,
- 0x3F14CF01,
- 0x3F153CF2,
- 0x3F15AA92,
- 0x3F1617E3,
- 0x3F1684E4,
- 0x3F16F196,
- 0x3F175DFA,
- 0x3F17CA11,
- 0x3F1835DC,
- 0x3F18A15A,
- 0x3F190C8C,
- 0x3F197774,
- 0x3F19E211,
- 0x3F1A4C65,
- 0x3F1AB66F,
- 0x3F1B2032,
- 0x3F1B89AC,
- 0x3F1BF2DF,
- 0x3F1C5BCB,
- 0x3F1CC471,
- 0x3F1D2CD1,
- 0x3F1D94EC,
- 0x3F1DFCC2,
- 0x3F1E6455,
- 0x3F1ECBA4,
- 0x3F1F32AF,
- 0x3F1F9979,
- 0x3F200000,
- 0x3F206646,
- 0x3F20CC4A,
- 0x3F21320E,
- 0x3F219792,
- 0x3F21FCD7,
- 0x3F2261DC,
- 0x3F22C6A3,
- 0x3F232B2B,
- 0x3F238F75,
- 0x3F23F383,
- 0x3F245753,
- 0x3F24BAE7,
- 0x3F251E3E,
- 0x3F25815A,
- 0x3F25E43B,
- 0x3F2646E1,
- 0x3F26A94D,
- 0x3F270B7F,
- 0x3F276D77,
- 0x3F27CF36,
- 0x3F2830BC,
- 0x3F28920A,
- 0x3F28F31F,
- 0x3F2953FD,
- 0x3F29B4A4,
- 0x3F2A1514,
- 0x3F2A754D,
- 0x3F2AD550,
- 0x3F2B351D,
- 0x3F2B94B5,
- 0x3F2BF417,
- 0x3F2C5345,
- 0x3F2CB23E,
- 0x3F2D1104,
- 0x3F2D6F95,
- 0x3F2DCDF3,
- 0x3F2E2C1E,
- 0x3F2E8A16,
- 0x3F2EE7DB,
- 0x3F2F456F,
- 0x3F2FA2D0,
- 0x3F300000,
- 0x3F305CFF,
- 0x3F30B9CC,
- 0x3F31166A,
- 0x3F3172D6,
- 0x3F31CF13,
- 0x3F322B20,
- 0x3F3286FE,
- 0x3F32E2AC,
- 0x3F333E2C,
- 0x3F33997C,
- 0x3F33F49F,
- 0x3F344F93,
- 0x3F34AA5A,
- 0x3F3504F3,
- 0x3F355F5F,
- 0x3F35B99E,
- };
- #define _UINT32 unsigned int
- #define _INT32 int
- float sqrtf(float x)
- {
- const _UINT32 numbits = (sizeof(sqrt_guess)) / (4 * 64) + 5;
- /* calculated at compile time(hopefully)--assumes minimal # of
- elements in sqrt_guess is 32 or an integral (power of two)*32
- */
- _UINT32 *u32tmp1 = (_UINT32 *)&x;
- _INT32 *s32tmp1 = (_INT32 *)&x;
- const _UINT32 bit_shift = 23 - numbits;
- const _UINT32 bit_mask = 0x007fffff & (~(sizeof(sqrt_guess) >> 2) << bit_shift);
- const _UINT32 first_several_sig_bits_of_x = (*u32tmp1) & bit_mask;
- const _INT32 biased_exp = (*u32tmp1) & 0x7f800000;
- float guess;
- float scaled_x;
- _UINT32 *u32tmp2 = (_UINT32 *)&guess;
- _UINT32 *u32tmp3 = (_UINT32 *)&scaled_x;
- // if(*(_UINT32*)&x & 0x80000000) /* either < 0 or -0 */
- // {
- // if((*(_UINT32*)&x) & 0x7fffffff) return NAN;
- // else return x; /* x = -0 */
- // }
- // if(!biased_exp) return 0.0f; //flush denormal to 0.0
- /* the condition below insures that we round x so that ||sqrt(x)-guess||<=||sqrt(x)-y|| for all y in sqrt_guess[](round to nearest)
- since sqrt is monotonically increasing --> ||sqrt(x)-sqrt(guess)|| <= ||sqrt(x)-sqrt(y)||
- we look at the remaining low order significant bits of x below the bit_mask.
- */
- #if 0
- #if _EWL_C99
- if ((x < 0) && (math_errhandling & MATH_ERRNO))
- {
- _EWL_LOCALDATA(errno) = EDOM;
- return(NAN);
- }
- #endif
- #endif
- if (biased_exp & 0x00800000) // if biased_exp is odd then the sqrt of the exponent is 2^^intsqrt(2)
- {
- (*u32tmp3) = 0x3E800000 + ((*u32tmp1) & 0x007fffff); // scaled_x in [.25,.5)
- (*u32tmp2) = sqrt_guess2[(first_several_sig_bits_of_x >> bit_shift)];
- }
- else
- {
- (*u32tmp3) = 0x3f000000 + ((*s32tmp1) & 0x007fffff); // scaled_x in [.5,1.0)
- (*u32tmp2) = sqrt_guess[(first_several_sig_bits_of_x >> bit_shift)];
- }
- guess += scaled_x / guess; // now have 12 sig bits
- guess = .25f * guess + (scaled_x / guess); // now we have about 24 sig bits
- /* we now reduce x to 2^^n*y where y is in [.5,1) we then calculate sqrt(x)=sqrt(2^^n)*sqrt(y)
- where if n is even we simply shift the exponent of guess appropriately or if n is odd we shift
- and multiply by sqrt(2) if n > 0 and 1/sqrt(2) if n > 0
- */
- s32tmp1 = (_INT32 *)&guess;
- if (biased_exp > 0x3f000000)
- (*s32tmp1) += (((biased_exp - 0x3e800000) >> 1) & 0xffbfffff); // this subtracts off bias(127=0x3f80...) // from biased_exp and one more which divides by two
- else
- (*s32tmp1) -= ((0x3f000000 - biased_exp) >> 1) & 0xffbfffff;
- return guess;
- }
- /*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
- /*
- * from: @(#)fdlibm.h 5.1 93/09/24
- */
- /* A union which permits us to convert between a float and a 32 bit
- int. */
- typedef union
- {
- float value;
- u32 word;
- } ieee_float_shape_type;
- /* Get a 32 bit int from a float. */
- #ifndef GET_FLOAT_WORD
- #define GET_FLOAT_WORD(i, d) \
- do \
- { \
- ieee_float_shape_type gf_u; \
- gf_u.value = (d); \
- (i) = gf_u.word; \
- } while (0)
- #endif
- /* Set a float from a 32 bit int. */
- #ifndef SET_FLOAT_WORD
- #define SET_FLOAT_WORD(d, i) \
- do \
- { \
- ieee_float_shape_type sf_u; \
- sf_u.word = (i); \
- (d) = sf_u.value; \
- } while (0)
- #endif
- /*
- * fabsf(x) returns the absolute value of x.
- */
- inline float fabsf(float x)
- {
- #if 1
- if (x < 0.0)
- {
- x = -x;
- }
- return x;
- #else
- u32 ix;
- GET_FLOAT_UWORD(ix, x);
- SET_FLOAT_UWORD(x, ix & 0x7fffffffU);
- return x;
- #endif
- }
- /* s_atanf.c -- float version of s_atan.c.
- * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
- */
- /*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
- // #include <math.h>
- // #include <math_private.h>
- static const float atanhi[] = {
- 4.6364760399e-01, /* atan(0.5)hi 0x3eed6338 */
- 7.8539812565e-01, /* atan(1.0)hi 0x3f490fda */
- 9.8279368877e-01, /* atan(1.5)hi 0x3f7b985e */
- 1.5707962513e+00, /* atan(inf)hi 0x3fc90fda */
- };
- static const float atanlo[] = {
- 5.0121582440e-09, /* atan(0.5)lo 0x31ac3769 */
- 3.7748947079e-08, /* atan(1.0)lo 0x33222168 */
- 3.4473217170e-08, /* atan(1.5)lo 0x33140fb4 */
- 7.5497894159e-08, /* atan(inf)lo 0x33a22168 */
- };
- static const float aT[] = {
- 3.3333334327e-01, /* 0x3eaaaaaa */
- -2.0000000298e-01, /* 0xbe4ccccd */
- 1.4285714924e-01, /* 0x3e124925 */
- -1.1111110449e-01, /* 0xbde38e38 */
- 9.0908870101e-02, /* 0x3dba2e6e */
- -7.6918758452e-02, /* 0xbd9d8795 */
- 6.6610731184e-02, /* 0x3d886b35 */
- -5.8335702866e-02, /* 0xbd6ef16b */
- 4.9768779427e-02, /* 0x3d4bda59 */
- -3.6531571299e-02, /* 0xbd15a221 */
- 1.6285819933e-02, /* 0x3c8569d7 */
- };
- static const float
- one = 1.0,
- huge = 1.0e30;
- float __atanf(float x)
- {
- float w, s1, s2, z;
- int ix, hx, id;
- GET_FLOAT_WORD(hx, x);
- ix = hx & 0x7fffffff;
- if (ix >= 0x50800000)
- { /* if |x| >= 2^34 */
- if (ix > 0x7f800000)
- return x + x; /* NaN */
- if (hx > 0)
- return atanhi[3] + atanlo[3];
- else
- return -atanhi[3] - atanlo[3];
- }
- if (ix < 0x3ee00000)
- { /* |x| < 0.4375 */
- if (ix < 0x31000000)
- { /* |x| < 2^-29 */
- if (huge + x > one)
- return x; /* raise inexact */
- }
- id = -1;
- }
- else
- {
- x = fabsf(x);
- if (ix < 0x3f980000)
- { /* |x| < 1.1875 */
- if (ix < 0x3f300000)
- { /* 7/16 <=|x|<11/16 */
- id = 0;
- x = ((float)2.0 * x - one) / ((float)2.0 + x);
- }
- else
- { /* 11/16<=|x|< 19/16 */
- id = 1;
- x = (x - one) / (x + one);
- }
- }
- else
- {
- if (ix < 0x401c0000)
- { /* |x| < 2.4375 */
- id = 2;
- x = (x - (float)1.5) / (one + (float)1.5 * x);
- }
- else
- { /* 2.4375 <= |x| < 2^66 */
- id = 3;
- x = -(float)1.0 / x;
- }
- }
- }
- /* end of argument reduction */
- z = x * x;
- w = z * z;
- /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */
- s1 = z * (aT[0] + w * (aT[2] + w * (aT[4] + w * (aT[6] + w * (aT[8] + w * aT[10])))));
- s2 = w * (aT[1] + w * (aT[3] + w * (aT[5] + w * (aT[7] + w * aT[9]))));
- if (id < 0)
- return x - x * (s1 + s2);
- else
- {
- z = atanhi[id] - ((x * (s1 + s2) - atanlo[id]) - x);
- return (hx < 0) ? -z : z;
- }
- }
- /* e_atan2f.c -- float version of e_atan2.c.
- * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
- */
- /*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
- // #include <math.h>
- // #include <math_private.h>
- static const float
- tiny = 1.0e-30,
- zero = 0.0,
- pi_o_4 = 7.8539818525e-01, /* 0x3f490fdb */
- pi_o_2 = 1.5707963705e+00, /* 0x3fc90fdb */
- pi = 3.1415927410e+00, /* 0x40490fdb */
- pi_lo = -8.7422776573e-08; /* 0xb3bbbd2e */
- float atan2f(float y, float x)
- {
- float z;
- int32_t k, m, hx, hy, ix, iy;
- GET_FLOAT_WORD(hx, x);
- ix = hx & 0x7fffffff;
- GET_FLOAT_WORD(hy, y);
- iy = hy & 0x7fffffff;
- if ((ix > 0x7f800000) ||
- (iy > 0x7f800000)) /* x or y is NaN */
- return x + y;
- if (hx == 0x3f800000)
- return __atanf(y); /* x=1.0 */
- m = ((hy >> 31) & 1) | ((hx >> 30) & 2); /* 2*sign(x)+sign(y) */
- /* when y = 0 */
- if (iy == 0)
- {
- switch (m)
- {
- case 0:
- case 1:
- return y; /* atan(+-0,+anything)=+-0 */
- case 2:
- return pi + tiny; /* atan(+0,-anything) = pi */
- case 3:
- return -pi - tiny; /* atan(-0,-anything) =-pi */
- }
- }
- /* when x = 0 */
- if (ix == 0)
- return (hy < 0) ? -pi_o_2 - tiny : pi_o_2 + tiny;
- /* when x is INF */
- if (ix == 0x7f800000)
- {
- if (iy == 0x7f800000)
- {
- switch (m)
- {
- case 0:
- return pi_o_4 + tiny; /* atan(+INF,+INF) */
- case 1:
- return -pi_o_4 - tiny; /* atan(-INF,+INF) */
- case 2:
- return (float)3.0 * pi_o_4 + tiny; /*atan(+INF,-INF)*/
- case 3:
- return (float)-3.0 * pi_o_4 - tiny; /*atan(-INF,-INF)*/
- }
- }
- else
- {
- switch (m)
- {
- case 0:
- return zero; /* atan(+...,+INF) */
- case 1:
- return -zero; /* atan(-...,+INF) */
- case 2:
- return pi + tiny; /* atan(+...,-INF) */
- case 3:
- return -pi - tiny; /* atan(-...,-INF) */
- }
- }
- }
- /* when y is INF */
- if (iy == 0x7f800000)
- return (hy < 0) ? -pi_o_2 - tiny : pi_o_2 + tiny;
- /* compute y/x */
- k = (iy - ix) >> 23;
- if (k > 60)
- z = pi_o_2 + (float)0.5 * pi_lo; /* |y/x| > 2**60 */
- else if (hx < 0 && k < -60)
- z = 0.0; /* |y|/x < -2**60 */
- else
- z = __atanf(fabsf(y / x)); /* safe to do y/x */
- switch (m)
- {
- case 0:
- return z; /* atan(+,+) */
- case 1:
- {
- u_int32_t zh;
- GET_FLOAT_WORD(zh, z);
- SET_FLOAT_WORD(z, zh ^ 0x80000000);
- }
- return z; /* atan(-,+) */
- case 2:
- return pi - (z - pi_lo); /* atan(+,-) */
- default: /* case 3 */
- return (z - pi_lo) - pi; /* atan(-,-) */
- }
- }
- long atol(const char *str)
- {
- return strtol(str, (char **)0, 10);
- }
- #if 0
- long atoi(const char *str)
- {
- return strtol(str, (char **)0, 10);
- }
- #endif
- void swap32(void *p)
- {
- char *ptr, c;
- if (!p)
- {
- return;
- }
- ptr = (char *)p;
- // swap 1,4
- c = *ptr;
- *ptr = *(ptr + 3);
- *(ptr + 3) = c;
- // swap 2,3
- c = *(ptr + 1);
- *(ptr + 1) = *(ptr + 2);
- *(ptr + 2) = c;
- return;
- }
- void swap16(void *p)
- {
- char *ptr, c;
- if (!p)
- {
- return;
- }
- ptr = (char *)p;
- // swap 1,2
- c = *ptr;
- *ptr = *(ptr + 1);
- *(ptr + 1) = c;
- return;
- }
- int test_round(void)
- {
- int n;
- float f;
- for (f = -2; f < 2; f += 0.1)
- {
- n = (int)rt_round(f);
- rt_printf("f=%f,n=%d.\r\n", f, n);
- }
- return 0;
- }
- /*------------------------------ 内部函数 -------------------------------------
- 内部函数以下划线‘_’开头,不需要检查参数的合法性.
- */
- /*------------------------------ 测试函数 -------------------------------------
- 一个实体文件必须带一个本模块的测试函数来进行单元测试,如果的确不方便在本模块中
- 进行单元测试,必须在此注明实际的测试位置(例如在哪个实体文件中使用哪个测试函数).
- */
- /*------------------------------ 文件结束 -------------------------------------
- */
|