number.tin 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  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.Inc <变量名> [<增量值>]
  144. // 将增量值叠加到变量原来的值之上。若变量值为空,则视同为 0。如增量值省略,则视同为 1。
  145. // };
  146. #alias {math.Inc} {
  147. #local math.local.var {%1};
  148. #local value {@defaultNum{%2;1}};
  149. #math {$math.local.var} {@defaultNum{${$math.local.var};0} + $value};
  150. };
  151. ///=== {
  152. // #@ math.ParseCN <中文数字串>
  153. // 将中文数字串转换成十进制整数。
  154. // 本函数也可以简写为 c2d,两个名称用途和用法完全相同。
  155. // };
  156. #func {c2d} {#return @math.ParseCN{%0}};
  157. #func {math.ParseCN} {
  158. #local string {%0};
  159. #local number1 {0}; #nop 个位(覆盖);
  160. #local number2 {0}; #nop 十百千位(加法);
  161. #local number3 {0}; #nop 万位(乘法);
  162. #local number4 {0}; #nop 亿位(乘法);
  163. #local ch {};
  164. #parse {$string} {ch} {
  165. #if { "$ch" == "{1|2|3|4|5|6|7|8|9|0|\.}" } {
  166. #format number1 {%d} {$number1$ch};
  167. #continue;
  168. };
  169. #switch {"$ch"} {
  170. #case {"零"} { #local number1 {0} };
  171. #case {"一"} { #local number1 {1} };
  172. #case {"二"} { #local number1 {2} };
  173. #case {"三"} { #local number1 {3} };
  174. #case {"四"} { #local number1 {4} };
  175. #case {"五"} { #local number1 {5} };
  176. #case {"六"} { #local number1 {6} };
  177. #case {"七"} { #local number1 {7} };
  178. #case {"八"} { #local number1 {8} };
  179. #case {"九"} { #local number1 {9} };
  180. #case {"十"} {
  181. #if { $number1 == 0 } {
  182. #format number1 {1};
  183. };
  184. #math number2 {$number2 + $number1 * 10};
  185. #format number1 {0};
  186. };
  187. #case {"百"} {
  188. #math number2 {$number2 + $number1 * 100};
  189. #format number1 {0};
  190. };
  191. #case {"千"} {
  192. #math number2 {$number2 + $number1 * 1000};
  193. #format number1 {0};
  194. };
  195. #case {"万"} {
  196. #math number3 {($number2 + $number1) * 10000};
  197. #format number1 {0};
  198. #format number2 {0};
  199. };
  200. #case {"亿"} {
  201. #math number4 {($number3 + $number2 + $number1) * 100000000};
  202. #format number1 {0};
  203. #format number2 {0};
  204. #format number3 {0};
  205. };
  206. };
  207. };
  208. #local number {};
  209. #math number {$number1 + $number2 + $number3 + $number4};
  210. #return $number;
  211. };
  212. ///=== {
  213. // #@ util.Grade <当前值> <地板结果> <阈值1> <结果1> [...]
  214. // 根据当前值,计算落入哪个区间,返回对应的结果。阈值被定义为区间的下边沿。
  215. // 如果当前值比最小的区间的阈值还要小,则返回地板结果。
  216. // };
  217. #func {util.Grade} {
  218. #local current {@defaultNum{%1;0}};
  219. #local default {%2};
  220. #local args {};
  221. #local grade {};
  222. #list args create {%0};
  223. #list args delete {1} {2};
  224. #list grade create {};
  225. #local count {0};
  226. #while { $count < &args[] } {
  227. #local threshold {$args[@math.Eval{$count + 1}]};
  228. #local value {$args[@math.Eval{$count + 2}]};
  229. #list grade {add} {{
  230. {threshold}{$threshold}
  231. {value}{$value}
  232. }};
  233. #math count {$count + 2};
  234. };
  235. #list grade {indexate} {threshold};
  236. #list grade {order};
  237. #local elem {};
  238. #local value {$default};
  239. #foreach {$grade[%*]} {elem} {
  240. #if { $current >= $elem[threshold] } {
  241. #local value {$elem[value]};
  242. };
  243. #else {
  244. #break;
  245. };
  246. };
  247. #return {$value};
  248. };