アットウィキロゴ

dcProgramming

「dcProgramming」の編集履歴(バックアップ)一覧はこちら

dcProgramming - (2010/09/06 (月) 21:50:41) の1つ前との変更点

追加された行は緑色になります。

削除された行は赤色になります。

*dc Programming **はじめに ***dcについて  dc は、arbitrary precision desk calculator であり、reverse Polish notation (RPN) を採用しているのが特徴である。今は使われていないかもしれないが、UNIX で配布されている。また、[[bc>bcProgramming]] というのもあるが、これは、C language like syntaxを特徴とし、かつては、dc用のprogram filesをoutputできたらしいが、GNU BC では、独立したプログラムとなっており、残念ながら、できない。 *** dcとForth  同じ RPN を採用しており、スタックが重要であることは共通しているが、やはり、微妙に異なる。dc の manual を見ないと書けない。 **dc ***導入 終了 q C-c 起動 command-line options -e 'expr' --expression='expr' 'expr' as dc commands -f 'file' --file='file' read and evaluate dc commands from 'file'  オプションの後に、パラメーターが残っている場合は追加fileとして解釈され、その内容が評価される。特に '-' というファイル名は standard input stream を指す。 ***数とarbitrary precision  decimal point 以下の数字の数(precision value)は default で 0、すなわち整数である。例えば、小数点以下20桁まで表示するとすれば、20k と入力する。負の数は'_'を使う。'-' は substraction という binary operation である。また、実数は小数形式であり、exponential notation はない。 *** commands - printing commands 'p' print TOS with a newline. TOS remains. (TOS=top of stack) 'n' print TOS without a newline. TOS is popped off. (GNU extension) 'P' print TOS without a newline. TOS is popped off. if a string, print it. if numbers <= 256 print the ASCII character if numbers > 256 print the value of the number modulo 256 'f' print the entire contents of the stack without altering anything. *** arithmetic + - * / % ^ '~' quotient & remainder '|' pops three values and computes the modular exponentiation. reduction modulus, exponent, base(GNU extension) 'v' square root *** stack control 'c' clear stack 'd' duplicate 'r' swap the top two values on the stack. (GNU extension) *** registers 'sr' store TOS into register r, popped TOS off. 'lr' push the value of register r, without popping off. 'Sr' push TOS into register r as TOS of register r. 'Lr' push TOS of register r onto the main stack. *** parameters 'i' input radix 'o' output radix input radix must be between 2 and 16 inclusive. outp radix must be at least 2. hexadecimalのとき、A through Fも使う。 注意)input radixをhexadecimalにして、再度、decimalに戻すときは、Aiと入力する。 1000 o 123456789 p => 123 456 789 100000 o 123456789 p => 01234 56789 *** strings dcはstringsについては、printするか、macroとして実行する。 registersでもstackでもstringsを保存できる。 [characters] eg) '[foo]P' prints 'foo' with no newline 'a' asciify eg)42ap=>* 13ap=>Carridge Return 'x' pop the value off the stack and execute as a macro . if it is a number, simply pushing back onto the stack. '>r' pops two values off the stack and compares them, if TOS is greater, execute the contents of register r. eg) '1 2>a' => invoking register 'a''s contents '!>r' not greater '=r' if equal '?' allows a macro to request input from the user 'q' exit 'Q' pops a value off the stack and uses it as a count of levels of macro execution to b *** status inquiry 'Z' number of digits (ignoring minus sign and decimal point) or number of characters X number of fraction digits .for a string, 0. 'x' current stack depth: the nubmer of objects on the stack before the execution of 'z' command. ***miscellaneous '!' run a system command '#' the rest of the line as a comment (GNU extension) ':r' store in the array r eg)<value><index>:r ';r' push from the array r. eg)<index>;r =><value> **サンプルプログラム  dc のサンプルプログラムはインターネットで探してもほとんど見つからない。 Morris & Cherry のmanualより # print the number 0-9 [lip1+ si li10a>]sa 0si lax ibm aixのcommands referenceより # factorial of n 最初の1行は1との大小で実行するマクロを切り替えていることに注意。 [d 1 >b d 1 <r] sf # if 1>n do b; if 1<n do r [d 1 +] sb # return f(n)=n*f(n-1) [d 1 - lf x *]sr # return f(n)=n*f(n-1) 10 lf x p => 3628800 5 lf x p => 120  注)comment である"#"はGNU extension Plan 9 manual # print the first ten values of n! [la1+dsa*pla10>y]sy 0sa1 lyx Ted Faber # average calculation 0st0sn (t:total, n:number) [lt+stln1+snz0<az0=d]sa [ltln/p0st0sn]sd $dc dc.avg - 5 k 1 2 3 4 5 6 7 8 9 10 lax 5.50000 Everything2.com # FizzBuzz in dc [sg []] sX [ [Buzz] l5 0!=X [Fizz] l3 0!=X n p sG ] sA [ln p sG] sB [ ln 3 % s3 ln 5 % s5 l3 l5 * d 0=A 0 !=B ln 1 + d sn 101 > C ] sC 1 sn lCx # shorter version [sg[]]sx1[ddd3%d[Fizz]r0!=xnr5%d[Buzz]r0!=xn*0=xpsg1+dd101>M]dsMx (注)FizzBuzzとは  one two three ... と続け、ある数の倍数をfizz, buzzに替える。  両方の倍数ならfizzbuzzとする。 MKS Toolkit9.1 Documentation Build7から # print out the first 12 elements of the Fibonacci sequence 1 sa 1 sb 2 sc [la lb + p lb sa sb lc 1 + d sc 13 >z] sz [lr*lr1-dsr0<a]sa 10sr1 lla p sx lp p sx lz x wikipedia (1) print the string 'equal' only if TOS=5 [1+2*] sm 3 lm x p [[equal]p] sm 5 =m (2) convert from meters to feet and inches dc -e '[[Enter a number (meters), or 0 to exit]psj]sh[q]sz \ [lhx?d0=z10k39.37009*.5+0k12~1/rn[feet]Pn[inches]P10Pdx]dx' (実際は1行) (3) Euclidean algorithm for search GCD dc -e '??[dSarLa%d0<a]dsaxp' # shortest dc -e '[a=]P?[b=]P?[dSarLa%d0<a]dsax+[GCD:]Pp' # more comfortable version **私が考えたプログラム例 **factorial 10! (1) 10sr1[lr*lr1-dsr0<a]dsaxp # two registers (1)' [lr*lr1-dsr0<a]sa 10sr1 laxp (2) 1 10[dsr*lr1-d0<a]dsax+p # two registers (注)tosが0となるので、+でしめる。 (3) 1 10[dSa*La1-d0<a]dsax+p # one register **(1/2)の階乗の計算 (1) (1/2)^1~(1/2)^17 20 k [2/dli1+dsi:ali17>a]sa 0sil lax # 計算結果は配列に収納 (2) n=1 0.5000の形で表示 [li1+d[= ]Pn[]Pdsi;an10anli17>b]sb # '10a'=newline n10anの代わりにpを用いると、stackにデータが残る。 0si lbx
*dc Programming **はじめに ***dcについて  dc は、arbitrary precision desk calculator であり、reverse Polish notation (RPN) を採用しているのが特徴である。今は使われていないかもしれないが、UNIX で配布されている。また、[[bc>bcProgramming]] というのもあるが、これは、C language like syntaxを特徴とし、かつては、dc用のprogram filesをoutputできたらしいが、GNU BC では、独立したプログラムとなっており、残念ながら、できない。 *** dcとForth  同じ RPN を採用しており、スタックが重要であることは共通しているが、やはり、微妙に異なる。dc の manual を見ないと書けない。 **dc ***導入 終了 q C-c 起動 command-line options -e 'expr' --expression='expr' 'expr' as dc [[commands]] -f 'file' --file='file' read and evaluate dc commands from 'file'  オプションの後に、パラメーターが残っている場合は追加fileとして解釈され、その内容が評価される。特に '-' というファイル名は standard input stream を指す。 ***数とarbitrary precision  decimal point 以下の数字の数(precision value)は default で 0、すなわち整数である。例えば、小数点以下20桁まで表示するとすれば、20k と入力する。負の数は'_'を使う。'-' は substraction という binary operation である。また、実数は小数形式であり、exponential notation はない。 *** commands - printing commands 'p' print TOS with a newline. TOS remains. (TOS=top of stack) 'n' print TOS without a newline. TOS is popped off. (GNU extension) 'P' print TOS without a newline. TOS is popped off. if a string, print it. if numbers <= 256 print the ASCII character if numbers > 256 print the value of the number modulo 256 'f' print the entire contents of the stack without altering anything. *** arithmetic + - * / % ^ '~' quotient & remainder '|' pops three values and computes the modular exponentiation. reduction modulus, exponent, base(GNU extension) 'v' square root *** stack control 'c' clear stack 'd' duplicate 'r' swap the top two values on the stack. (GNU extension) *** registers 'sr' store TOS into register r, popped TOS off. 'lr' push the value of register r, without popping off. 'Sr' push TOS into register r as TOS of register r. 'Lr' push TOS of register r onto the main stack. *** parameters 'i' input radix 'o' output radix input radix must be between 2 and 16 inclusive. outp radix must be at least 2. hexadecimalのとき、A through Fも使う。 注意)input radixをhexadecimalにして、再度、decimalに戻すときは、Aiと入力する。 1000 o 123456789 p => 123 456 789 100000 o 123456789 p => 01234 56789 *** strings dcはstringsについては、printするか、macroとして実行する。 registersでもstackでもstringsを保存できる。 [characters] eg) '[foo]P' prints 'foo' with no newline 'a' asciify eg)42ap=>* 13ap=>Carridge Return 'x' pop the value off the stack and execute as a macro . if it is a number, simply pushing back onto the stack. '>r' pops two values off the stack and compares them, if TOS is greater, execute the contents of register r. eg) '1 2>a' => invoking register 'a''s contents '!>r' not greater '=r' if equal '?' allows a macro to request input from the user 'q' exit 'Q' pops a value off the stack and uses it as a count of levels of macro execution to b *** status inquiry 'Z' number of digits (ignoring minus sign and decimal point) or number of characters X number of fraction digits .for a string, 0. 'x' current stack depth: the nubmer of objects on the stack before the execution of 'z' command. ***miscellaneous '!' run a system command '#' the rest of the line as a comment (GNU extension) ':r' store in the array r eg)<value><index>:r ';r' push from the array r. eg)<index>;r =><value> **サンプルプログラム  dc のサンプルプログラムはインターネットで探してもほとんど見つからない。 Morris & Cherry のmanualより # print the number 0-9 [lip1+ si li10a>]sa 0si lax ibm aixのcommands referenceより # factorial of n 最初の1行は1との大小で実行するマクロを切り替えていることに注意。 [d 1 >b d 1 <r] sf # if 1>n do b; if 1<n do r [d 1 +] sb # return f(n)=n*f(n-1) [d 1 - lf x *]sr # return f(n)=n*f(n-1) 10 lf x p => 3628800 5 lf x p => 120  注)comment である"#"はGNU extension Plan 9 manual # print the first ten values of n! [la1+dsa*pla10>y]sy 0sa1 lyx Ted Faber # average calculation 0st0sn (t:total, n:number) [lt+stln1+snz0<az0=d]sa [ltln/p0st0sn]sd $dc dc.avg - 5 k 1 2 3 4 5 6 7 8 9 10 lax 5.50000 Everything2.com # FizzBuzz in dc [sg []] sX [ [Buzz] l5 0!=X [Fizz] l3 0!=X n p sG ] sA [ln p sG] sB [ ln 3 % s3 ln 5 % s5 l3 l5 * d 0=A 0 !=B ln 1 + d sn 101 > C ] sC 1 sn lCx # shorter version [sg[]]sx1[ddd3%d[Fizz]r0!=xnr5%d[Buzz]r0!=xn*0=xpsg1+dd101>M]dsMx (注)FizzBuzzとは  one two three ... と続け、ある数の倍数をfizz, buzzに替える。  両方の倍数ならfizzbuzzとする。 MKS Toolkit9.1 Documentation Build7から # print out the first 12 elements of the Fibonacci sequence 1 sa 1 sb 2 sc [la lb + p lb sa sb lc 1 + d sc 13 >z] sz [lr*lr1-dsr0<a]sa 10sr1 lla p sx lp p sx lz x wikipedia (1) print the string 'equal' only if TOS=5 [1+2*] sm 3 lm x p [[equal]p] sm 5 =m (2) convert from meters to feet and inches dc -e '[[Enter a number (meters), or 0 to exit]psj]sh[q]sz \ [lhx?d0=z10k39.37009*.5+0k12~1/rn[feet]Pn[inches]P10Pdx]dx' (実際は1行) (3) Euclidean algorithm for search GCD dc -e '??[dSarLa%d0<a]dsaxp' # shortest dc -e '[a=]P?[b=]P?[dSarLa%d0<a]dsax+[GCD:]Pp' # more comfortable version **私が考えたプログラム例 **factorial 10! (1) 10sr1[lr*lr1-dsr0<a]dsaxp # two registers (1)' [lr*lr1-dsr0<a]sa 10sr1 laxp (2) 1 10[dsr*lr1-d0<a]dsax+p # two registers (注)tosが0となるので、+でしめる。 (3) 1 10[dSa*La1-d0<a]dsax+p # one register **(1/2)の階乗の計算 (1) (1/2)^1~(1/2)^17 20 k [2/dli1+dsi:ali17>a]sa 0sil lax # 計算結果は配列に収納 (2) n=1 0.5000の形で表示 [li1+d[= ]Pn[]Pdsi;an10anli17>b]sb # '10a'=newline n10anの代わりにpを用いると、stackにデータが残る。 0si lbx

表示オプション

横に並べて表示:
変化行の前後のみ表示:
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。