ALGO_AlgorithmBase_ATY.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. /**
  2. * @file ALGO_AlgorithmBase_ATY.h
  3. *
  4. * @param Project ALGO_Algorithm_ATY_LIB
  5. *
  6. * @author ATY
  7. *
  8. * @copyright
  9. * - Copyright 2017 - 2023 MZ-ATY
  10. * - This code follows:
  11. * - MZ-ATY Various Contents Joint Statement -
  12. * <a href="https://mengze.top/MZ-ATY_VCJS">
  13. * https://mengze.top/MZ-ATY_VCJS</a>
  14. * - CC 4.0 BY-NC-SA -
  15. * <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">
  16. * https://creativecommons.org/licenses/by-nc-sa/4.0/</a>
  17. * - Your use will be deemed to have accepted the terms of this statement.
  18. *
  19. * @brief Familiar functions of base algorithm
  20. *
  21. * @version
  22. * - 1_01_220601 > ATY
  23. * -# Preliminary version, first Release
  24. ********************************************************************************
  25. */
  26. #ifndef __ALGO_AlgorithmBase_ATY_H
  27. #define __ALGO_AlgorithmBase_ATY_H
  28. #include "INCLUDE_ATY.h"
  29. /******************************* For user *************************************/
  30. // #define __DEBUG_ALGO_AlgorithmBase_ATY
  31. /******************************************************************************/
  32. /*
  33. | **Type** | **16 bit platform** | **32 bit platform** | **64 bit platform** |
  34. |:---------------------:|:-------------------:|:-------------------:|:-------------------:|
  35. | **char** | 1 byte | 1 byte | 1 byte |
  36. | **short** | 2 byte | 2 byte | 2 byte |
  37. | **int** | 2 byte | 4 byte | 4 byte |
  38. | **unsigned int** | 2 byte | 4 byte | 4 byte |
  39. | **float** | 4 byte | 4 byte | 4 byte |
  40. | **double** | 8 byte | 8 byte | 8 byte |
  41. | **long** | 4 byte | 4 byte | 8 byte |
  42. | **long long** | 8 byte | 8 byte | 8 byte |
  43. | **unsigned long** | 4 byte | 4 byte | 8 byte |
  44. | **Pointer** | 2 byte | 4 byte | 8 byte |
  45. | **Max storage space** | 2^16 | 2^32 | 2^64 |
  46. */
  47. /**
  48. * @brief Allocate memory space
  49. * @param name variate name
  50. * @param type variate type
  51. */
  52. #define ALGO_MALLOC(name, type) ((type *) malloc((name) * sizeof(type)))
  53. /**
  54. * @brief Get a byte at the specified address
  55. * @param addr address
  56. */
  57. #define ALGO_MEM_BYTE(addr) (*((byte *)(addr)))
  58. /**
  59. * @brief Gets the number of specified bits
  60. * @param n bit position
  61. */
  62. #define ALGO_BITMASK(n) ((uint32_t)1 << n)
  63. /**
  64. * @brief Get absolute value
  65. * @param x value to deal
  66. */
  67. #define ALGO_ABS(x) ((x) > 0 ? (x) : -(x))
  68. /**
  69. * @brief Get the max between 2 numbers
  70. * @param x value to deal
  71. * @param y value to deal
  72. */
  73. #define ALGO_MAX(x, y) (((x) > (y)) ? (x) : (y))
  74. /**
  75. * @brief Get the min between 2 numbers
  76. * @param x value to deal
  77. * @param y value to deal
  78. */
  79. #define ALGO_MIN(x, y) (((x) < (y)) ? (x) : (y))
  80. /**
  81. * @brief Converts a character to uppercase
  82. * @param c character to deal
  83. */
  84. #define ALGO_UPCASE(c) (((c) >= 'a' && (c) <= 'z') ? ((c) - 0x20) : (c))
  85. /**
  86. * @brief Determines if the character is a decimalism number
  87. * @param c character to deal
  88. */
  89. #define ALGO_DECCHK(c) ((c) >= '0' && (c) <= '9')
  90. /**
  91. * @brief Determines if the character is a hexadecimal number
  92. * @param c character to deal
  93. */
  94. #define ALGO_HEXCHK(c) \
  95. (((c) >= '0' && (c) <= '9') \
  96. || ((c) >= 'A' && (c) <= 'F') \
  97. || ((c) >= 'a' && (c) <= 'f'))
  98. /**
  99. * @brief Returns the number of array elements
  100. * @param a array to deal
  101. */
  102. #define ALGO_ARR_SIZE(a) (sizeof((a)) / sizeof((a[0])))
  103. /**
  104. * @brief Combine two uint8 to one uint16 in LSB format
  105. * @param a high bit of uint16
  106. * @param b low bit of uint16
  107. */
  108. #define ALGO_COMB16(a, b) ((((uint16_t)(a)) << 8) + (b))
  109. /**
  110. * @brief Combine four uint8 to one uint32 in LSB format
  111. * @param a high bit of uint32
  112. * @param b mid high bit of uint32
  113. * @param c mid low bit of uint32
  114. * @param d low bit of uint32
  115. */
  116. #define ALGO_COMB32(a, b, c, d) \
  117. ((((uint32_t)(a)) << 24) \
  118. + (((uint32_t)(b)) << 16)) \
  119. + ((((uint32_t)(c)) << 8) + (d))
  120. /**
  121. * @brief Get the low byte of a uint16
  122. * @param x value to deal
  123. */
  124. #define ALGO_UINT16_L(x) ((uint8_t)((uint16_t)(x) & 0xFF))
  125. /**
  126. * @brief Get the high byte of a uint16
  127. * @param x value to deal
  128. */
  129. #define ALGO_UINT16_H(x) ((uint8_t)((uint16_t)(x) >> 8))
  130. /**
  131. * @brief Change to a character
  132. * @param a value to deal
  133. * @note equal to add '', accept less than 3 characters
  134. */
  135. #define ALGO_CHAR(a) @#a
  136. /**
  137. * @brief Change to string
  138. * @param a value to deal
  139. * @note equal to add ""
  140. */
  141. #define _ALGO_STR(a) #a
  142. #define ALGO_STR(a) ALGO_STR(a)
  143. /**
  144. * @brief Combine two value or characters to string
  145. * @param a value to deal
  146. * @param b value to deal
  147. */
  148. #define _ALGO_CAT(a, b) a##b
  149. #define ALGO_CAT(a, b) _ALGO_CAT(a, b)
  150. /**
  151. * @brief Change value to bool
  152. * @param x value to deal
  153. */
  154. #define ALGO_BOOL(x) (x) ? 1 : 0
  155. /**
  156. * @brief Invert value truth-value
  157. * @param x value to deal
  158. */
  159. #define ALGO_NOT(x) (x) ? 0 : 1
  160. /**
  161. * @brief AND two value
  162. * @param x value to deal
  163. * @param y value to deal
  164. */
  165. #define ALGO_AND(x, y) ((x) && (y)) ? 1 : 0
  166. /**
  167. * @brief OR two value
  168. * @param x value to deal
  169. * @param y value to deal
  170. */
  171. #define ALGO_OR(x, y) ((x) || (y)) ? 1 : 0
  172. /**
  173. * @brief ROL rotate shift left
  174. * @param x value to deal
  175. * @param n shift bits
  176. * @todo X&0X00FF or etc
  177. */
  178. #define ALGO_ROTATE_LEFT(x, n) ((x) << (n)) | ((x) >> ((sizeof(x)) - (n)))
  179. /**
  180. * @brief ROR rotate shift right
  181. * @param x value to deal
  182. * @param n shift bits
  183. * @todo X&0X00FF or etc
  184. */
  185. #define ALGO_ROTATE_RIGHT(x, n) ((x) >> (n)) | ((x) << ((sizeof(x)) - (n)))
  186. /**
  187. * @brief Invert little-endian and big-endian
  188. * @param x value to deal
  189. */
  190. #define ALGO_INVERT_BELE(x) \
  191. { \
  192. if(sizeof(x) == sizeof(uint8_t)) {} \
  193. else if(sizeof(x) == sizeof(uint16_t)) \
  194. {x = (uint16_t)((((uint16_t)(x) & 0x00FF) << 8) | (((uint16_t)(x) & 0xFF00) >> 8));} \
  195. else if(sizeof(x) == sizeof(uint32_t)) \
  196. {x = (uint32_t)((((uint32_t)(x) & 0xFF000000) >> 24) | (((uint32_t)(x) & 0x00FF0000) >> 8) \
  197. | (((uint32_t)(x) & 0x0000FF00) << 8) | (((uint32_t)(x) & 0x000000FF) << 24));} \
  198. }
  199. /**
  200. * @brief Invert value every bit(LSB <-> MSB)
  201. * @param x value to deal
  202. */
  203. #define ALGO_INVERT_BITS(x) \
  204. { \
  205. x = ((x & 0xAAAAAAAAAAAAAAAA) >> 1) | ((x & 0x5555555555555555) << 1); \
  206. x = ((x & 0xCCCCCCCCCCCCCCCC) >> 2) | ((x & 0x3333333333333333) << 2); \
  207. x = ((x & 0xF0F0F0F0F0F0F0F0) >> 4) | ((x & 0x0F0F0F0F0F0F0F0F) << 4); \
  208. ALGO_SWAP_BELE(x); \
  209. }
  210. /**
  211. * @brief Invert uint8 value every bit(LSB <-> MSB)
  212. * @param x value to deal
  213. */
  214. #define ALGO_INVERT_BITS_BYTE(x) \
  215. { \
  216. x = ((x & 0xAA) >> 1) | ((x & 0x55) << 1); \
  217. x = ((x & 0xCC) >> 2) | ((x & 0x33) << 2); \
  218. x = ((x & 0xF0) >> 4) | ((x & 0x0F) << 4); \
  219. }
  220. #define ALGO_Uint8ToBin(n) \
  221. ( \
  222. ((n >> 21) & 0x80) | \
  223. ((n >> 18) & 0x40) | \
  224. ((n >> 15) & 0x20) | \
  225. ((n >> 12) & 0x10) | \
  226. ((n >> 9) & 0x08) | \
  227. ((n >> 6) & 0x04) | \
  228. ((n >> 3) & 0x02) | \
  229. ((n ) & 0x01) \
  230. )
  231. #define ALGO_Bin(n) ALGO_Uint8ToBin(0x##n##l)
  232. /* Easy way to implement Invert ***********************************************/
  233. void ALGO_InvertUint8_Group(uint8_t* genBuf, uint8_t* srcBuf);
  234. void ALGO_InvertUint16_Group(uint16_t* genBuf, uint16_t* srcBuf);
  235. void ALGO_InvertUint32_Group(uint32_t* genBuf, uint32_t* srcBuf);
  236. void ALGO_InvertBitsN_Group(uint32_t* genBuf, uint32_t* srcBuf, uint8_t len);
  237. /* End of Easy way to implement Invert ****************************************/
  238. /**
  239. * @brief Swap numbers in easy way
  240. * @param x value to deal
  241. * @param y value to deal
  242. */
  243. #define ALGO_SWAP_EASY(x, y)\
  244. x = x + y;\
  245. y = x - y;\
  246. x = x - y;
  247. /**
  248. * @brief Swap numbers
  249. * @param dataType x & y data type
  250. * @param vN variableNum is set to deal with multiple calls in one scope
  251. * @param x value to deal
  252. * @param y value to deal
  253. * @note x & y must be the same type
  254. */
  255. #define ALGO_SWAP(dataType, vN, x, y)\
  256. {\
  257. dataType swap_t##vN = x;\
  258. x = y;\
  259. y = swap_t##vN;\
  260. }
  261. /**
  262. * @brief Swap numbers in addr (not tested)
  263. * @param vN variableNum is set to deal with multiple calls in one scope
  264. * @param x value to deal
  265. * @param y value to deal
  266. * @note x & y must be the same type
  267. */
  268. #define ALGO_SWAP_ADDR(vN, x, y)\
  269. {\
  270. uint32_t swapAddr_t##vN = x; \
  271. x = y; \
  272. y = swapAddr_t##vN; \
  273. }
  274. /**
  275. * @brief Sort numbers in group with low first
  276. * @param dataType dataInGroup data type
  277. * @param vN variableNum is set to deal with multiple calls in one scope
  278. * @param dataInGroup data group which need to sort
  279. */
  280. #define ALGO_Sort(dataType, vN, dataInGroup) \
  281. { \
  282. uint32_t as_i##vN, as_j##vN, dataInGroupSize##vN; \
  283. dataInGroupSize##vN = sizeof(dataInGroup)/sizeof(dataType); \
  284. for(as_i##vN = 0; as_i##vN < dataInGroupSize##vN; as_i##vN++) \
  285. { \
  286. for(as_j##vN = as_i##vN + 1; as_j##vN < dataInGroupSize##vN; as_j##vN++) \
  287. { \
  288. if(dataInGroup[as_i##vN] > dataInGroup[as_j##vN]) \
  289. { \
  290. ALGO_SWAP(dataType, _as_0, dataInGroup[as_i##vN], dataInGroup[as_j##vN]); \
  291. } \
  292. } \
  293. } \
  294. }
  295. /**
  296. * @brief Sort numbers in group with high first
  297. * @param dataType dataInGroup data type
  298. * @param vN variableNum is set to deal with multiple calls in one scope
  299. * @param dataInGroup data group which need to sort
  300. */
  301. #define ALGO_Sort_High(dataType, vN, dataInGroup) \
  302. { \
  303. uint32_t as_i##vN, as_j##vN, dataInGroupSize##vN; \
  304. dataInGroupSize##vN = sizeof(dataInGroup)/sizeof(dataType); \
  305. for(as_i##vN = 0; as_i##vN < dataInGroupSize##vN; as_i##vN++) \
  306. { \
  307. for(as_j##vN = as_i##vN + 1; as_j##vN < dataInGroupSize##vN; as_j##vN++) \
  308. { \
  309. if(dataInGroup[as_i##vN] < dataInGroup[as_j##vN]) \
  310. { \
  311. ALGO_SWAP(dataType, _as_0, dataInGroup[as_i##vN], dataInGroup[as_j##vN]); \
  312. } \
  313. } \
  314. } \
  315. }
  316. /**
  317. * @brief Calculate averange with delete extremum
  318. * @param dataType x & y data type
  319. * @param vN variableNum is set to deal with multiple calls in one scope
  320. * @param dataInGroup data group which need to deel
  321. * @param dataOut output number after deel
  322. * @note dataOut & dataInGroup must be the same type
  323. */
  324. #define ALGO_AverageInDelExtremum(dataType, vN, dataInGroup, dataOut) \
  325. { \
  326. uint32_t aaide_i##vN, dataInGroupSize##vN; \
  327. dataInGroupSize##vN = sizeof(dataInGroup)/sizeof(dataType); \
  328. ALGO_Sort(dataType, _aaide_0, dataInGroup); \
  329. dataOut = 0; \
  330. for(aaide_i##vN = 1; aaide_i##vN < dataInGroupSize##vN - 1; aaide_i##vN++) \
  331. dataOut += dataInGroup[aaide_i##vN]; \
  332. dataOut /= dataInGroupSize##vN - 2; \
  333. }
  334. float ALGO_MATH_POW_EASY(float x, uint8_t n);
  335. int ALGO_MATH_POW_QUICK(int x, int n);
  336. float ALGO_MATH_POW(float x, int n);
  337. int ALGO_MATH_SQRT(int x);
  338. float ALGO_MATH_LogLn(float num);
  339. float NumberSuitScop(float valueIn, float scopMin, float scopMax, float step);
  340. #ifdef __DEBUG_ALGO_AlgorithmBase_ATY
  341. void ALGO_Swap_Test(void);
  342. void ALGO_Sort_Test(void);
  343. void ALGO_AverageInDelExtremum_Test(void);
  344. void ALGO_INVERT_Test(void);
  345. void ALGO_Test_Whole(void);
  346. #endif /* __DEBUG_ALGO_AlgorithmBase_ATY */
  347. #endif /* __ALGO_AlgorithmBase_ATY_H */
  348. /******************************** End Of File *********************************/