選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 
 

270 行
11 KiB

  1. /*
  2. *********************************************************************************************************
  3. * uC/LIB
  4. * Custom Library Modules
  5. *
  6. * Copyright 2004-2021 Silicon Laboratories Inc. www.silabs.com
  7. *
  8. * SPDX-License-Identifier: APACHE-2.0
  9. *
  10. * This software is subject to an open source license and is distributed by
  11. * Silicon Laboratories Inc. pursuant to the terms of the Apache License,
  12. * Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
  13. *
  14. *********************************************************************************************************
  15. */
  16. /*
  17. *********************************************************************************************************
  18. *
  19. * MATHEMATIC OPERATIONS
  20. *
  21. * Filename : lib_math.c
  22. * Version : V1.39.01
  23. *********************************************************************************************************
  24. * Note(s) : (1) NO compiler-supplied standard library functions are used in library or product software.
  25. *
  26. * (a) ALL standard library functions are implemented in the custom library modules :
  27. *
  28. * (1) \<Custom Library Directory>\lib_*.*
  29. *
  30. * (2) \<Custom Library Directory>\Ports\<cpu>\<compiler>\lib*_a.*
  31. *
  32. * where
  33. * <Custom Library Directory> directory path for custom library software
  34. * <cpu> directory name for specific processor (CPU)
  35. * <compiler> directory name for specific compiler
  36. *
  37. * (b) Product-specific library functions are implemented in individual products.
  38. *
  39. *********************************************************************************************************
  40. * Notice(s) : (1) The Institute of Electrical and Electronics Engineers and The Open Group, have given
  41. * us permission to reprint portions of their documentation. Portions of this text are
  42. * reprinted and reproduced in electronic form from the IEEE Std 1003.1, 2004 Edition,
  43. * Standard for Information Technology -- Portable Operating System Interface (POSIX),
  44. * The Open Group Base Specifications Issue 6, Copyright (C) 2001-2004 by the Institute
  45. * of Electrical and Electronics Engineers, Inc and The Open Group. In the event of any
  46. * discrepancy between these versions and the original IEEE and The Open Group Standard,
  47. * the original IEEE and The Open Group Standard is the referee document. The original
  48. * Standard can be obtained online at http://www.opengroup.org/unix/online.html.
  49. *********************************************************************************************************
  50. */
  51. /*
  52. *********************************************************************************************************
  53. * INCLUDE FILES
  54. *********************************************************************************************************
  55. */
  56. #define MICRIUM_SOURCE
  57. #define LIB_MATH_MODULE
  58. #include <lib_math.h>
  59. /*
  60. *********************************************************************************************************
  61. * LOCAL DEFINES
  62. *********************************************************************************************************
  63. */
  64. /*
  65. *********************************************************************************************************
  66. * LOCAL CONSTANTS
  67. *********************************************************************************************************
  68. */
  69. /*
  70. *********************************************************************************************************
  71. * LOCAL DATA TYPES
  72. *********************************************************************************************************
  73. */
  74. /*
  75. *********************************************************************************************************
  76. * LOCAL TABLES
  77. *********************************************************************************************************
  78. */
  79. /*
  80. *********************************************************************************************************
  81. * LOCAL GLOBAL VARIABLES
  82. *********************************************************************************************************
  83. */
  84. RAND_NBR Math_RandSeedCur; /* Cur rand nbr seed. */
  85. /*
  86. *********************************************************************************************************
  87. * LOCAL FUNCTION PROTOTYPES
  88. *********************************************************************************************************
  89. */
  90. /*
  91. *********************************************************************************************************
  92. * LOCAL CONFIGURATION ERRORS
  93. *********************************************************************************************************
  94. */
  95. /*
  96. *********************************************************************************************************
  97. * Math_Init()
  98. *
  99. * Description : (1) Initialize Mathematic Module :
  100. *
  101. * (a) Initialize random number seed value
  102. *
  103. *
  104. * Argument(s) : none.
  105. *
  106. * Return(s) : none.
  107. *
  108. * Caller(s) : Application.
  109. *
  110. * Note(s) : (2) IEEE Std 1003.1, 2004 Edition, Section 'rand() : DESCRIPTION' states that "if rand()
  111. * is called before any calls to srand() are made, the same sequence shall be generated
  112. * as when srand() is first called with a seed value of 1".
  113. *********************************************************************************************************
  114. */
  115. void Math_Init (void)
  116. {
  117. Math_RandSetSeed((RAND_NBR)RAND_SEED_INIT_VAL); /* See Note #2. */
  118. }
  119. /*
  120. *********************************************************************************************************
  121. * Math_RandSetSeed()
  122. *
  123. * Description : Set the current pseudo-random number generator seed.
  124. *
  125. * Argument(s) : seed Initial (or current) value to set for the pseudo-random number sequence.
  126. *
  127. * Return(s) : none.
  128. *
  129. * Caller(s) : Application.
  130. *
  131. * Note(s) : (1) IEEE Std 1003.1, 2004 Edition, Section 'rand() : DESCRIPTION' states that "srand()
  132. * ... uses the argument as a seed for a new sequence of pseudo-random numbers to be
  133. * returned by subsequent calls to rand()".
  134. *
  135. * (2) 'Math_RandSeedCur' MUST always be accessed exclusively in critical sections.
  136. *
  137. * See also 'Math_Rand() Note #1b'.
  138. *********************************************************************************************************
  139. */
  140. void Math_RandSetSeed (RAND_NBR seed)
  141. {
  142. CPU_SR_ALLOC();
  143. CPU_CRITICAL_ENTER();
  144. Math_RandSeedCur = seed;
  145. CPU_CRITICAL_EXIT();
  146. }
  147. /*
  148. *********************************************************************************************************
  149. * Math_Rand()
  150. *
  151. * Description : Calculate the next pseudo-random number.
  152. *
  153. * Argument(s) : none.
  154. *
  155. * Return(s) : Next pseudo-random number in the sequence after 'Math_RandSeedCur'.
  156. *
  157. * Caller(s) : Application.
  158. *
  159. * Note(s) : (1) (a) The pseudo-random number generator is implemented as a Linear Congruential
  160. * Generator (LCG).
  161. *
  162. * (b) The pseudo-random number generated is in the range [0, RAND_LCG_PARAM_M].
  163. *
  164. * See also 'Math_RandSeed() Note #1'.
  165. *
  166. * (2) (a) IEEE Std 1003.1, 2004 Edition, Section 'rand() : DESCRIPTION' states that "rand()
  167. * ... need not be reentrant ... [and] is not required to be thread-safe".
  168. *
  169. * (b) However, in order to implement Math_Rand() as re-entrant; 'Math_RandSeedCur' MUST
  170. * always be accessed & updated exclusively in critical sections.
  171. *
  172. * See also 'Math_RandSeed() Note #2'.
  173. *********************************************************************************************************
  174. */
  175. RAND_NBR Math_Rand (void)
  176. {
  177. RAND_NBR seed;
  178. RAND_NBR rand_nbr;
  179. CPU_SR_ALLOC();
  180. CPU_CRITICAL_ENTER();
  181. seed = Math_RandSeedCur;
  182. rand_nbr = Math_RandSeed(seed);
  183. Math_RandSeedCur = rand_nbr;
  184. CPU_CRITICAL_EXIT();
  185. return (rand_nbr);
  186. }
  187. /*
  188. *********************************************************************************************************
  189. * Math_RandSeed()
  190. *
  191. * Description : Calculate the next pseudo-random number.
  192. *
  193. * Argument(s) : seed Initial (or current) value for the pseudo-random number sequence.
  194. *
  195. * Return(s) : Next pseudo-random number in the sequence after 'seed'.
  196. *
  197. * Caller(s) : Math_Rand(),
  198. * Application.
  199. *
  200. * Note(s) : (1) (a) BSD/ANSI-C implements rand() as a Linear Congruential Generator (LCG) :
  201. *
  202. * (A) random_number = [(a * random_number ) + b] modulo m
  203. * n + 1 n
  204. *
  205. * where
  206. * (1) (a) random_number Next random number to generate
  207. * n+1
  208. * (b) random_number Previous random number generated
  209. * n
  210. *
  211. * (2) a = RAND_LCG_PARAM_A LCG multiplier
  212. * (3) b = RAND_LCG_PARAM_B LCG incrementor
  213. * (4) m = RAND_LCG_PARAM_M + 1 LCG modulus
  214. *
  215. * (b) The pseudo-random number generated is in the range [0, RAND_LCG_PARAM_M].
  216. *
  217. See also 'lib_math.h RANDOM NUMBER DEFINES Note #1b'.
  218. *
  219. * (2) (a) IEEE Std 1003.1, 2004 Edition, Section 'rand() : DESCRIPTION' states that "rand()
  220. * ... need not be reentrant ... [and] is not required to be thread-safe".
  221. *
  222. * (b) However, Math_RandSeed() is re-entrant since it calculates the next random number
  223. * using ONLY local variables.
  224. *********************************************************************************************************
  225. */
  226. RAND_NBR Math_RandSeed (RAND_NBR seed)
  227. {
  228. RAND_NBR rand_nbr;
  229. rand_nbr = (((RAND_NBR)RAND_LCG_PARAM_A * seed) + (RAND_NBR)RAND_LCG_PARAM_B) % ((RAND_NBR)RAND_LCG_PARAM_M + 1u);
  230. return (rand_nbr);
  231. }