/****************************************************************************** 版权所有: 文件名称: 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 // #include 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 // #include 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 // #include 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; } /*------------------------------ 内部函数 ------------------------------------- 内部函数以下划线‘_’开头,不需要检查参数的合法性. */ /*------------------------------ 测试函数 ------------------------------------- 一个实体文件必须带一个本模块的测试函数来进行单元测试,如果的确不方便在本模块中 进行单元测试,必须在此注明实际的测试位置(例如在哪个实体文件中使用哪个测试函数). */ /*------------------------------ 文件结束 ------------------------------------- */