絶対値を得るには,用意されている関数だけを用いて,
sqrt(x^2)
などとすることもできなくはないですが,こんなことは普通やりません。
awk で絶対値を与える関数は標準では用意されていません。絶対値を求めるには,次のような関数を作ります。
# x の絶対値を求める # 使用例: x = abs(-10.95) function abs(x) { return (x < 0) ? -x : x }平方根を求める関数はあります(sqrt)。もしないとしたらどのような関数を作りますか?
二数の小さい方
二数の大きい方
引数の符号により-1,0,1を返す
四捨五入
ある数を超えない最大の整数値
ある数より大きい最小の整数値
タンジェント
アークコサイン
アークサイン
アークタンジェント(1)
アークタンジェント(2)
平方根
ベータ関数
ガンマ関数
階乗(1)
階乗(2)
組合せの数(1)
組合せの数(2)
ポアソン分布の確率
二項分布の確率
カイ二乗分布の確率
半角数字を全角数字に変換
半角アスキー文字を全角アスキー文字に変換
年月日からユリウス日
ユリウス日を年月日に変換
ユリウス日から年
ユリウス日から月
ユリウス日から日
ユリウス日から曜日
ある年が閏年かどうかを判定する
# x, y の小さい方を求める # 使用例: x = min(10, 5) function min(x, y) { return (x < y) ? x : y }関数目次へ戻る
# x, y の大きい方を求める # 使用例: x = max(10, 5) function max(x, y) { return (x > y) ? x : y }関数目次へ戻る
# x > 0 のとき 1 # x = 0 のとき 0 # x < 0 のとき -1 を返す # 使用例: y = sign(z) function sign(x) { return (x > 0) ? 1 : (x == 0) ? 0 : -1 # 上の1行は以下と同じことを表す # if (x > 0) { # return 1 # } # else if (x == 0) { # return 0 # } # else { # return -1; # } }関数目次へ戻る
# x を四捨五入した値を返す # 使用例: y = round(z) function round(x) { return (x > 0) ? int(x+0.5) : int(x-0.5) }関数目次へ戻る int,round,floor,ceil の違い
# x を超えない最大の整数値を返す # 使用例: y = floor(x) function floor(x) { return (x > 0) ? int(x) : (int(x) == x) ? x : int(x)-1 # 上の1行は以下と同じことを表す # if (x > 0) { # return int(x) # } # else if (int(x) == x) { # return x # } # else { # return int(x)-1 # } }関数目次へ戻る int,round,floor,ceil の違い
# x より大きい最小の整数値を返す # 使用例: y = ceil(z) function ceil(x) { return (int(x) == x) ? x : (x > 0) ? int(x)+1 : int(x) # 上の1行は以下と同じことを表す # if (int(x) == x) { # return x # } # else if (x > 0) { # return int(x)+1 # } # else { # return int(x) # } }関数目次へ戻る int,round,floor,ceil の違い
# x の tangent を求める # 使用例: y = tan(z) function tan(x) { return sin(x)/cos(x) }関数目次へ戻る
# 1 ≧ x ≧ 0 の arc_cosine を求める # 使用例: y = arc_cosine(z) # 必要とする関数: arc_sine function arc_cosine(x) { return arc_sine(sqrt(1-x^2)) }関数目次へ戻る
# 1 ≧ x ≧ 0 の arc_sine を求める # 使用例: y = arc_sine(z) function arc_sine(x, a0, a1, a2) { if (x == 0) { return 0 } a0 = x*sqrt(1-x^2) a1 = x for (;;) { a2 = a1*sqrt(2*a1/(a1+a0)) if (abs(a2-a1)/a1 < 1e-14) { return a2 } a0 = a1 a1 = a2 } }関数目次へ戻る
# x の arctangent を求める # 使用例: y = arc_tangent(z) function arc_tangent(x, a, b, a2, b2) { a = 1/sqrt(1+x^2) b = 1 for (;;) { a2 = (a+b)/2 b2 = sqrt(a2*b) if (abs(a2 - b2)/b2 < 1e-14) { return x/sqrt(a2*b2*(1+x^2)) } a = a2 b = b2 } }関数目次へ戻る
# x の arctangent を求める # 使用例: y = atan(z) function atan(x) { return atan2(x, 1) }関数目次へ戻る
# 平方根を求める関数 sqrt2.awk # function sqrt2(x, x1, x2) { if (x < 0) exit(1) if (x == 0) return 0 x1 = 1 for (;;) { x2 = (x1+x/x1)/2 if (abs(x2-x1)/x2 < 1e-10) { return x2 } x1 = x2 } }関数目次へ戻る
# ベータ関数 # 値が求められないときには,"Inf" という文字列を返すことに注意 function beta(x, y, z1, z2, z3) { z1 = gamma(x) z2 = gamma(y) z3 = gamma(x+y) return (z1 == "Inf" || z2 == "Inf" || z3 == "Inf") ? "Inf" : z1/z3*z2 }関数目次へ戻る
# ガンマ関数 # 必要とする関数 abs # 値が求められないときには,"Inf" という文字列を返すことに注意 function gamma(x, a, b, z, factor, i, m, mg) { if (x > 171.6) { printf "gamma: Overflow.\n" > "/dev/stderr" return "Inf" } if (x <= 1.5) { if (x >= 0.5) { a = x-1.0 factor = 1.0 } else { m = int(x) a = x-m if (a == 0) { printf "gamma: Invalid argument.\n" > "/dev/stderr" return "Inf" } if (a >= -0.5) { mg = abs(m)+1 } else { mg = abs(m)+2 a++ } z = 1.0 for (i = 0; i < mg; i++) { z *= x x++ } factor = 1.0/z } } else { m = int(x) a = x-m if (a <= 0.5) { mg = m-1 } else { mg = m a-- } z = 1.0 for (i = 0; i < mg; i++) { z *= (x-1.0) x-- } factor = z } b = ((((((((-0.42202e-11*a +0.120028e-10)*a +0.923397e-10)*a -0.12736143e-8)*a +0.62756218e-8)*a -0.1595268e-9)*a-0.2054743152e-6)*a +0.13385015466e-5)*a -0.25889950224e-5)*a b = ((((((((((b -0.175458597517e-4)*a +0.1455961421399e-3)*a -0.3608378162548e-3)*a -0.80432977560424699e-3)*a +0.80232730222673465e-2)*a -0.1764524455014432e-1)*a -0.24552490005400017e-1)*a +0.19109110138769151)*a -0.23309373642178674)*a -0.42278433509846714)*a +1.0 return factor/(1.0+a)/b }関数目次へ戻る
# 整数値 n(n ≧ 0 )の階乗 n! を求める # 使用例: x = factorial(10) function factorial(n, retv, i) { retv = 1 for (i = 1; i <= n; i++) { retv *= i } return retv }関数目次へ戻る
# 整数値 n(n ≧ 0 )の階乗 n! を求める(再帰関数) # 使用例: x = factorial2(10) function factorial2(n) { if (n == 0) { return 1 } else { return n*factorial2(n-1) } }関数目次へ戻る
# n から m (n ≧ m ≧ 0 )を取り出す組合せを求める # 使用例: x = combination(10, 5) function combination(n, m, i, c) { c = 1 k = min(n, n-m) for (i = 1; i <= k; i++) { c *= (n-i+1)/i } return c }関数目次へ戻る
# 組合せ(なるべく正確に求める) function combination2(n, m, numerator, denominator, p, pivot, i, j, k, comb) { comb = 1.0 p = min(m, n-m) if (p > 0) { for (i = 1; i <= p; i++) { numerator[i] = n-p+i denominator[i] = i } for (k = 2; k <= p; k++) { pivot = denominator[k] if (pivot > 1) { j = -((n-p)%k) for (i = k; i <=p; i +=k) { numerator[i+j] /= pivot denominator[i] /= pivot } } } for (i = 1; i <= p; i++) { if (numerator[i] > 1) { comb *= numerator[i] } } } return comb }関数目次へ戻る
# ポアソン定数 lambda のポアソン分布の確率 f(lambda, x) を求める # 使用例: y = Poisson(lambda, x) function Poisson(lambda, x) { return exp(-lambda)*lambda^x/factorial(x) }関数目次へ戻る
# 母比率 p の二項分布の確率 f(p, n, x) を求める # n は試行回数,x は対象事象の観察回数 # 使用例: y = Binomial(p, n, x) # 必要とする関数: combination function Binomial(p, n, x) { return combination(n, x) * p^x * (1-p)^(n-x) }関数目次へ戻る
# 自由度 df のカイ二乗分布において確率密度 f(x) を求める # 使用例: chi_dist(2.34, 2) function chi_dist(x, df) { return x^(df/2.0-1.0) * exp(-x/2) / 2^(df/2.0) / gamma(df/2.0) }関数目次へ戻る
# 0 〜 9 の数字の列の各文字を,0〜9に置き換える # 使用例: i2zen("0123456789012") # i2zen(12345) function i2zen(num, i, retv) { for (i = 1; i <= length(num); i++) { retv = retv substr("0123456789", substr(num, i, 1)*2+1, 2) } return retv }関数目次へ戻る
# いわゆるアスキー半角文字列の各文字を,いわゆる全角文字に置き換える # 使用例: a2zen("01234ABCxyz#@") function a2zen(str, i, retv) { for (i = 1; i <= length(str); i++) { retv = retv substr(" !”#$%&’()*+,−./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[¥]^_‘abcdefghijklmnopqrstuvwxyz{|}〜", index(" !\"\#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", substr(str, i, 1))*2-1, 2) } return retv }関数目次へ戻る
# 西暦年月日からユリウス日を得る # y 年 m 月 d 日 function J_day(y, m, d) { return d-32075+int( 1461*(y+4800+ int( (m-14)/12) )/4 ) \ +int( 367*(m-2-int( (m-14)/12 )*12)/12 ) \ -int( 3*( int( (y+4900+int( (m-14)/12 ))/100 ) )/4 ) }関数目次へ戻る
# ユリウス日 jul から西暦年を取り出す function year(jul) { return substr(date(jul), 1, 4) }関数目次へ戻る
# ユリウス日 jul から月を取り出す function month(jul) { return substr(date(jul), 6, 2)+0 }関数目次へ戻る
# ユリウス日 jul から日を取り出す function day(jul) { return substr(date(jul), 9, 2)+0 }関数目次へ戻る
# 指定された西暦年月日の曜日を求める # 引数 # y 西暦年(4桁) # m 月 # d 日 # i 戻り値の種類指定 # 戻り値 # i が 1 のとき y年 m月 d日の 曜日を表す漢字1文字 # i が 1 以外のとき y年 m月 d日の 曜日を表す英字3文字 # 必要とする関数: J_day function week(y, m, d, i) { return (i == 1) ? substr("日月火水木金土", ((J_day(y, m, d)+1)%7)*2+1, 2) \ : substr("SunMonTueWedThuFriSat", ((J_day(y, m, d)+1)%7)*3+1, 3) }関数目次へ戻る
# ユリウス日から西暦年月日を得る function date(jul, l, n, iy, jm, kd) { l = jul+68569 n = int(4*l/146097) l -= int((146097*n+3)/4) iy = int(4000*(l+1)/1461001) l -= int(1461*iy/4)-31 jm = int(80*l/2447) kd = l-int(2447*jm/80) l = int(jm/11) jm = jm+2-12*l iy = 100*(n-49)+iy+l return sprintf("%4d/%02d/%02d", iy, jm, kd) }関数目次へ戻る
# 西暦年 y を与えてその年が閏年かどうかを判定する function uruudosi(y) { return (month(J_day(y, 2, 29)) == 2) ? 1 : 0 }関数目次へ戻る