number.tin 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. #nop vim: set filetype=tt:;
  2. /*
  3. 本文件属于 PaoTin++ 的一部分。
  4. PaoTin++ © 2020~2023 的所有版权均由担子炮(dzp <danzipao@gmail.com>) 享有并保留一切法律权利
  5. 你可以在遵照 GPLv3 协议的基础之上使用、修改及重新分发本程序。
  6. */
  7. #nop 本文件是 xtintin 的一部分,实现了一些数值计算函数;
  8. ///=== {
  9. ///// 数值计算函数:
  10. //
  11. // #@ math.Eval <字符串>
  12. // 将给定字符串作为算术表达式,进行算术运算,并返回结果。参见 #help math。
  13. // 本函数也可以简写为 eval,两个名称用途和用法完全相同。
  14. // };
  15. #func {eval} {#math result {%0}};
  16. #func {math.Eval} {#math result {%0}};
  17. ///=== {
  18. // #@ math.Random <最小值> <最大值>
  19. // 给出一个介于最小值和最大值之间的随机整数,注意随机范围包含了最小值和最大值,为闭区间。
  20. // 本函数也可以简写为 random,两个名称用途和用法完全相同。
  21. // };
  22. #func {random} {#return @math.Random{%0}};
  23. #func {math.Random} {
  24. #local min {%1};
  25. #local max {%2};
  26. #local range {@math.Eval{$max - $min + 1}};
  27. #math result { ( 1 d $range ) + $min - 1 };
  28. };
  29. ///=== {
  30. // #@ math.Int <值>
  31. // 对参数值按照四舍五入取整。
  32. // 本函数也可以简写为 int,两个名称用途和用法完全相同。
  33. //
  34. // #@ math.Floor <值>
  35. // 对参数值向下取整。
  36. //
  37. // #@ math.Ceil <值>
  38. // 对参数值向上取整。
  39. // };
  40. #func {int} {#return @math.Floor{1.000 * %0 + 0.5}};
  41. #func {math.Int} {#return @math.Floor{1.000 * %0 + 0.5}};
  42. #func {math.Floor} {#format result {%d} {1.000 * %0}};
  43. #func {math.Ceil} {
  44. #local value @math.Eval{1.000 * %0};
  45. #local floor @math.Floor{%0};
  46. #if { $floor < $value } {
  47. #return @math.Eval{$floor + 1};
  48. };
  49. #else {
  50. #return $floor;
  51. };
  52. };
  53. ///=== {
  54. // #@ math.Power <底数> <指数>
  55. // 幂运算。
  56. //
  57. // #@ math.Root <幂> <指数>
  58. // 开方运算。
  59. // };
  60. #func {math.Power} {#return @math.Eval{%1 ** %2}};
  61. #func {math.Root} {#return @math.Eval{%1 // %2}};
  62. ///=== {
  63. // #@ math.Abs <值>
  64. // 取绝对值。
  65. //
  66. // #@ math.Sign <值>
  67. // 取符号。
  68. // };
  69. #func {math.Abs} {#if {%0 >= 0} {#return %0} {#math result {- %0}}};
  70. #func {math.Sign} {#if {%0 >= 0} {#return 1} {#return -1}};
  71. ///=== {
  72. // #@ math.Max <值1> [<值2> ...]
  73. // 求一系列值的最大值。
  74. // 本函数也可以简写为 max,两个名称用途和用法完全相同。
  75. // };
  76. #func {max} {#return @math.Max{%0}};
  77. #func {math.Max} {
  78. #var result {%1};
  79. #local elem {};
  80. #foreach {%0} {elem} {
  81. #if { "$elem" == "" } {
  82. #continue;
  83. };
  84. #if { $elem > $result } {
  85. #var result {$elem};
  86. };
  87. };
  88. };
  89. ///=== {
  90. // #@ math.Min <值1> [<值2> ...]
  91. // 求一系列值的最小值。
  92. // 本函数也可以简写为 min,两个名称用途和用法完全相同。
  93. // };
  94. #func {min} {#return @math.Min{%0}};
  95. #func {math.Min} {
  96. #var result {%1};
  97. #local elem {};
  98. #foreach {%0} {elem} {
  99. #if { "$elem" == "" } {
  100. #continue;
  101. };
  102. #if { $elem < $result } {
  103. #var result {$elem};
  104. };
  105. };
  106. };
  107. ///=== {
  108. // #@ math.Sum <值1> [<值2> ...]
  109. // 求一系列值的和。
  110. // 本函数也可以简写为 sum,两个名称用途和用法完全相同。
  111. // };
  112. #func {sum} {#return @math.Sum{%0}};
  113. #func {math.Sum} {
  114. #local sum {0};
  115. #local tmp {};
  116. #foreach {%0} {tmp} {
  117. #math sum {$sum + $tmp};
  118. };
  119. #return {$sum};
  120. };
  121. ///=== {
  122. // #@ math.Avg <值1> [<值2> ...]
  123. // 求一系列值的算术平均值。
  124. // 本函数也可以简写为 avg,两个名称用途和用法完全相同。
  125. // };
  126. #func {avg} {#return @math.Avg{%0}};
  127. #func {math.Avg} {
  128. #var sum {0};
  129. #local tmp {};
  130. #local count {0};
  131. #foreach {%0} {tmp} {
  132. #math sum {$sum + $tmp};
  133. #math count {$count + 1};
  134. };
  135. #if { $count == 0 } {
  136. #return 0;
  137. };
  138. #else {
  139. #return @math.Eval{$sum / $count};
  140. };
  141. };
  142. ///=== {
  143. // #@ math.ParseCN <中文数字串>
  144. // 将中文数字串转换成十进制整数。
  145. // 本函数也可以简写为 c2d,两个名称用途和用法完全相同。
  146. // };
  147. #func {c2d} {#return @math.ParseCN{%0}};
  148. #func {math.ParseCN} {
  149. #local string {%0};
  150. #local number1 {0}; #nop 个位(覆盖);
  151. #local number2 {0}; #nop 十百千位(加法);
  152. #local number3 {0}; #nop 万位(乘法);
  153. #local number4 {0}; #nop 亿位(乘法);
  154. #local ch {};
  155. #parse {$string} {ch} {
  156. #if { "$ch" == "{1|2|3|4|5|6|7|8|9|0|\.}" } {
  157. #format number1 {%d} {$number1$ch};
  158. #continue;
  159. };
  160. #switch {"$ch"} {
  161. #case {"零"} { #local number1 {0} };
  162. #case {"一"} { #local number1 {1} };
  163. #case {"二"} { #local number1 {2} };
  164. #case {"三"} { #local number1 {3} };
  165. #case {"四"} { #local number1 {4} };
  166. #case {"五"} { #local number1 {5} };
  167. #case {"六"} { #local number1 {6} };
  168. #case {"七"} { #local number1 {7} };
  169. #case {"八"} { #local number1 {8} };
  170. #case {"九"} { #local number1 {9} };
  171. #case {"十"} {
  172. #if { $number1 == 0 } {
  173. #format number1 {1};
  174. };
  175. #math number2 {$number2 + $number1 * 10};
  176. #format number1 {0};
  177. };
  178. #case {"百"} {
  179. #math number2 {$number2 + $number1 * 100};
  180. #format number1 {0};
  181. };
  182. #case {"千"} {
  183. #math number2 {$number2 + $number1 * 1000};
  184. #format number1 {0};
  185. };
  186. #case {"万"} {
  187. #math number3 {($number2 + $number1) * 10000};
  188. #format number1 {0};
  189. #format number2 {0};
  190. };
  191. #case {"亿"} {
  192. #math number4 {($number3 + $number2 + $number1) * 100000000};
  193. #format number1 {0};
  194. #format number2 {0};
  195. #format number3 {0};
  196. };
  197. };
  198. };
  199. #local number {};
  200. #math number {$number1 + $number2 + $number3 + $number4};
  201. #return $number;
  202. };
  203. ///=== {
  204. // #@ util.Grade <当前值> <地板结果> <阈值1> <结果1> [...]
  205. // 根据当前值,计算落入哪个区间,返回对应的结果。阈值被定义为区间的下边沿。
  206. // 如果当前值比最小的区间的阈值还要小,则返回地板结果。
  207. // };
  208. #func {util.Grade} {
  209. #local current {@defaultNum{%1;0}};
  210. #local default {%2};
  211. #local args {};
  212. #local grade {};
  213. #list args create {%0};
  214. #list args delete {1} {2};
  215. #list grade create {};
  216. #local count {0};
  217. #while { $count < &args[] } {
  218. #local threshold {$args[@math.Eval{$count + 1}]};
  219. #local value {$args[@math.Eval{$count + 2}]};
  220. #list grade {add} {{
  221. {threshold}{$threshold}
  222. {value}{$value}
  223. }};
  224. #math count {$count + 2};
  225. };
  226. #list grade {indexate} {threshold};
  227. #list grade {order};
  228. #local elem {};
  229. #local value {$default};
  230. #foreach {$grade[%*]} {elem} {
  231. #if { $current >= $elem[threshold] } {
  232. #local value {$elem[value]};
  233. };
  234. #else {
  235. #break;
  236. };
  237. };
  238. #return {$value};
  239. };