概要
通常の四則演算をはじめとして、三角関数、順列や組み合わせを後置記法で出力できるようにした*1。たとえば、"10 5 c" と入力すれば、袋に入っている"10" 個の玉から "5" 個を選び出す組み合わせ("C"ombination)を出力する。プログラムは上記のリンク先からダウンロード出来る。
これにより、数値の計算に括弧を使用する必要がなくなった。従来、"( (51 / 23) + (84 * 92) ) * 21" のように丸括弧を使用していた式を、"51 23 / 84 92 * + 21 *" のように、テンキーのみで入力できる式として記述できるようになったわけだ*2。
仕様一覧
演算・変数 - AutoHotkeyJpを参照のこと。
記号や文字列 | 使用例 | 出力例 | 説明 |
---|---|---|---|
+ | 1 2 + | 3 | |
- | 1 2 - | -1 | |
* | 1 2 * | 2 | |
/ | 1 2 / | 0.500000 | |
// | 1 2 // | 0.5 | |
% | 7 6 % | 1 | |
^ | 7 6 ^ | 117649 | |
P | 7 6 p | 5040 | 順列(permutation) |
C | 7 6 c | 7 | 組み合わせ(combination) |
記号や文字列 | 使用例 | 出力例 | 説明 |
---|---|---|---|
Abs | -10 Abs | 10 | 絶対値 |
Ceil | 10.456 ceil | 11 | |
Floor | 10.456 Floor | 10 | |
Round | 10.456 Round | 10 | |
Sqrt | 10 Sqrt | 3.162278 | |
Exp | 10 Exp | 22026.465795 | |
Log | 10 Log | 1.000000 | |
Ln | 10 Ln | 2.302585 | |
Sin | 10 Sin | -0.544021 | |
Cos | 10 Cos | -0.839072 | |
Tan | 10 Tan | 0.648361 | |
ASin | 1 ASin | 1.570796 | |
ACos | 0.1 ACos | 1.470629 | |
ATan | 10 ATan | 1.471128 |
記号や文字列 | 使用例 | 出力例 | 説明 |
---|---|---|---|
! | 20! | 2432902008176640000 | 階乗 |
課題
AutoHotkey 本家から続いている桁あふれの問題には、後に対処することにしよう。
ソース
ソースは以下の通りである。
#persistent #singleinstance force ;;; [AHK_L] Arrays ;;; http://www.autohotkey.com/forum/topic49736.html #include Array.ahk SetTitleMatchMode,3 Gui, Font , S14, consolas Gui, Add, Edit , vargv gInputEditForm R1 W300 , Input: Gui, Add, Edit , vOutputVar R1 W300 ReadOnly , Result: Gui, Show, , RPN calculator return #IfWinActive, RPN calculator Enter:: Send,{Space} return NumpadEnter:: Send,{Space} return InputEditForm: Gui, Submit, NoHide rpn(argv) return rpn(argv) { stack := Array() i := 0 Loop, Parse, argv, %A_Space% { if (A_LoopField = "") continue if A_LoopField is number { stack.append(A_LoopField) } else { if (RegExMatch(A_LoopField, "(\d+)!$", num)) ; 階乗 ! { stack.append(factorial(num1)) } else { if (i < 1) exit b := stack_pop(stack, i) i := i - 1 if (A_LoopField = "Abs") stack.append(Abs(b)) else if (A_LoopField = "Ceil") stack.append(Ceil(b)) else if (A_LoopField = "Floor") stack.append(Floor(b)) else if (A_LoopField = "Round") stack.append(Round(b)) else if (A_LoopField = "Sqrt") stack.append(Sqrt(b)) else if (A_LoopField = "Exp") stack.append(Exp(b)) else if (A_LoopField = "Log") stack.append(Log(b)) else if (A_LoopField = "Ln") stack.append(Ln(b)) else if (A_LoopField = "Sin") stack.append(Sin(b)) else if (A_LoopField = "Cos") stack.append(Cos(b)) else if (A_LoopField = "Tan") stack.append(Tan(b)) else if (A_LoopField = "ASin") stack.append(ASin(b)) else if (A_LoopField = "ACos") stack.append(ACos(b)) else if (A_LoopField = "ATan") stack.append(ATan(b)) else { ;; 数値が何も残っていないときには ;; 何も処理せず終了する if (i < 1) exit a := stack_pop(stack, i) i := i - 1 ;; 演算・変数 - AutoHotkeyJp ;; https://sites.google.com/site/autohotkeyjp/reference/commands/index_calc if (A_LoopField = "+") stack.append(a + b) else if (A_LoopField = "-") stack.append(a - b) else if (A_LoopField = "*") stack.append(a * b) else if (A_LoopField = "/") stack.append(a / b) else if (A_LoopField = "//") stack.append(a // b) else if (A_LoopField = "%") stack.append( Mod(a, b) ) else if (A_LoopField = "^") stack.append( a ** b ) else if (A_LoopField = "p") ; 順列 (permutation) { if (a < b) exit stack.append( factorial(a) // factorial(a - b) ) } else if (A_LoopField = "c") ; 組み合わせ (combination) { if (a < b) exit stack.append( factorial(a) // (factorial(b) * factorial(a - b)) ) } } } } i := i + 1 } ;; show_stack(stack) if (stack.len() = 1) show_result( stack[1] ) else show_result( "" ) return } stack_pop(ByRef obj, index) { item := obj[index] obj.pop() return item } show_result(item) { GuiControl, , OutputVar, % item return } show_stack(obj) { all_stack := "" loop,% obj.len() all_stack := obj[A_index] . "`n" . all_stack tooltip,% all_stack return } ;;; 階乗 factorial(n) { return % (n = 0) ? 1 : n * factorial(n -1) }
後日追記:逆ポーランド記法用の計算機で、スタックの内容を表示できるようにした - blechmusik2の日記を公開した。
*2:[Enter] で空白を出力するよう調整している。