Mathクラスには、基本的な数学関数が用意されています。 これらはいずれもMathクラスの静的メソッドとして提供されます。 ここでは、Mathクラスのメソッドについて解説します。
Mathクラスで使用することができる数学関数・数値演算と、対応するメソッドを表にまとめると次のようになります。 個々のメソッドの詳細については順に解説していきます。
関数 | 対応するメソッド呼び出し | 解説 | ||
---|---|---|---|---|
絶対値・符合 | 絶対値 |x| | Math.Abs(x) | 解説へ | |
符号関数 sgn x | Math.Sign(x) | |||
最大・最小 | 最大 max(x, y) | Math.Max(x, y) | 解説へ | |
最小 min(x, y) | Math.Min(x, y) | |||
丸め・端数処理 | 天井関数 ⌈x⌉ | Math.Ceiling(x) | 解説へ | |
床関数 ⌊x⌋ | Math.Floor(x) | |||
切り捨て trunc(x), fix(x) | Math.Truncate(x) | |||
四捨五入 | Math.Round(x, MidpointRounding.AwayFromZero) | |||
最近接偶数への丸め round(x) | Math.Round(x, MidpointRounding.ToEven) | |||
累乗・累乗根 | 累乗 xy | Math.Pow(x, y) | 解説へ | |
ネイピア数の累乗 ex | Math.Exp(x) | |||
平方根 √x | Math.Sqrt(x) | |||
累乗根 n√x | Math.Pow(x, 1.0 / n) | |||
対数 | 自然対数 ln x | Math.Log(x) | 解説へ | |
常用対数 log10x | Math.Log10(x) | |||
対数 logax | Math.Log(x, a) | |||
三角関数 | 三角関数 | sin x | Math.Sin(x) | 解説へ |
cos x | Math.Cos(x) | |||
tan x | Math.Tan(x) | |||
逆正接 tan-1 (y/x) 直交座標(x, y)の偏角 |
Math.Atan2(y, x) | 解説へ | ||
逆三角関数 | sin-1x | Math.Asin(x) | 解説へ | |
cos-1x | Math.Acos(x) | |||
tan-1x | Math.Atan(x) | |||
双曲線関数 | sinh x | Math.Sinh(x) | 解説へ | |
cosh x | Math.Cosh(x) | |||
tanh x | Math.Tanh(x) | |||
関数 | 対応するメソッド呼び出し | 解説 |
Mathクラスのメソッドの使い方
Mathクラスで提供される数学関数はいずれも静的メソッドとなっているため、他のクラスの静的メソッドと同様にクラス名.メソッド(引数)
の形式で呼び出します。
C# 6.0以降ではusing static
ディレクティブ、VB 7以降ではImports
ステートメントでクラス名を指定することにより、クラス名を省略してメソッドを呼び出すことができるようになります。 これを用いることで、次のようにMathクラスの記述を省略してメソッド呼び出しを行えます。
これはMathクラスのメソッドを多用するコードで特に有用ですが、不必要に濫用すればどのクラスのメソッドを呼び出しているかわかりにくくなるというデメリットもあります。
6.0より前のC#では、using
ディレクティブは名前空間のみにしか使用できないので、静的メンバをインポートによるクラス名の省略はできません。 ただ、using
ディレクティブでクラス名にエイリアス(別名)を付けることができるため、これを用いて短い記述にすることは可能です。 VBのImports
ステートメントでも同様にエイリアスを付けることが出来ます。
さらに、Mathクラスのメソッド名はすべてPascal形式となっている(大文字から始まる)ので、C#のように大文字・小文字の違いを意識する言語では、呼び出すメソッド名をすべて小文字にするとコンパイルエラーとなります。 C言語のmath.h
の関数(sqrt
やsin
など)を使っているコードを移植するような場合には注意が必要です。
絶対値・符号 (Abs, Sign)
絶対値を求めるにはAbsメソッド、値の符号(正負)を求めるにはSignメソッドを使用します。 Absメソッド・Signメソッドともに戻り値は引数と同じ型になります。 Signメソッドでは、引数の値が正の場合は+1、負の場合は-1、0の場合は0が返されます。
Absメソッドと整数最小値のオーバーフロー
整数型の場合、AbsメソッドでMinValueと同じ値の絶対値を求めようとするとオーバーフローとなるためOverflowExceptionがスローされる点に注意が必要です。 これは、例えばintの最小値(int.MinValue)である-2147483648
の絶対値+2147483648
は、intの最大値(int.MaxValue)である+2147483647
を超えていて、intの範囲内で表せないためです。
型と最小値・最大値については型の種類・サイズ・精度・値域 §.型のサイズ・精度と値域、オーバーフロー時の動作の変更については整数型のオーバーフローとチェックをご覧ください。
Signメソッドと無限大(±∞)と非数(NaN)の扱い
Double型の場合、値が無限大でもSignメソッドは適切な符号を返しますが、非数(NaN, 0/0)の場合はArithmeticExceptionをスローします。
最大・最小 (Min, Max)
二つの値のうち大きい方を求めるにはMaxメソッド、小さい方を求めるにはMinメソッドを使用します。 Maxメソッド・Minメソッドも、戻り値は引数と同じ型になります。
3組以上の値の最大値・最小値
Maxメソッド・Minメソッドともに引数は2つしかとらないため、3つ以上の値から最大値・最小値を求めたい場合、複数回呼び出す必要があります。
配列内・コレクション内の最大値・最小値
配列やコレクションなどから最大値・最小値を求める場合は、LINQの拡張メソッドMaxメソッドまたはMinメソッドを使うこともできます。
値がSortedSetに格納されている場合は、SortedSet.Maxプロパティ・SortedSet.Minプロパティを使うことでも最大値・最小値を求めることも出来ます。 詳しくはジェネリックコレクション(7) HashSetとSortedSetをご覧ください。
実数の丸め・端数処理 (Truncate, Ceiling, Floor, Round)
Double・Decimalの丸め・端数処理を行うには、次のメソッドを使用します。 目的に応じて5種類の丸め方法を用いることができます。 各メソッドの動作は次のとおりです。
- Truncate (切り捨て)
- 指定した数値の端数部分を切り捨てた整数(数直線上で0の方向にある次の整数)に丸められる。
- Ceiling (正の無限大への丸め)
- 指定した数値以下の最大の整数(数直線上で正の方向にある次の整数)に丸められる。
- Floor (負の無限大への丸め)
- 指定した数値以上の最小の整数(数直線上で負の方向にある次の整数)に丸められる。
- Round
- 丸めの方法MidpointRoundingを指定して整数への丸めを行います。 特に指定しなかった場合はMidpointRounding.ToEvenの動作になります。
- MidpointRounding.ToEven (最近接偶数への丸め、銀行家丸め)
- 数値の端数は偶数方向に丸められる。
- MidpointRounding.AwayFromZero (四捨五入)
- 数値の端数はゼロから遠い方に丸められる。
これらのメソッドの戻り値はいずれもDoubleもしくはDecimalとなるため、整数型への代入を目的として端数処理する場合は、メソッドを呼び出して端数処理した結果をさらに整数型へとキャストする必要があります。
C#での整数型へのキャストはTruncateメソッドによる切り捨てと同じ動作、VBでのCInt
等による型変換はMidpointRounding.ToEven
を指定したRoundメソッドによる最近接偶数への丸めと同じ動作となります。
各メソッドの端数処理の動作を比較すると次のようになります。 0.25刻みの数について、それぞれのメソッドを使って端数処理した場合の結果を並べています。
有効桁数を指定した丸め
Roundメソッドは丸めを行う小数部分の桁数を第二引数で指定することができます。 例えば、四捨五入を行うMidpointRounding.AwayFromZeroと組み合わせて桁数を指定することで、小数点1桁へ四捨五入する(小数点2桁目で四捨五入)、といったことができます。
整数の四捨五入
Mathクラスには整数を任意の桁数で四捨五入する、例えば5を10に、49を50に四捨五入するとメソッドは用意されていません。 このような目的には、Math.Roundを使って次のようなコードを実装する必要があります。
積・商と剰余 (BigMul, DivRem)
オーバーフローを起こさずにint/Integer同士の積を求めたい場合、BigMulメソッドを用いることができます。 このメソッドは二つのint/Integerを引数にとり、それらの積をlong/Long型で返します。
オーバーフローのチェックの有効/無効の切り替えやその際の動作の違いなどについては整数型のオーバーフローとチェックを参照してください。
DivRemメソッドを用いると、整数同士の除算による商と剰余を同時に求めることができます。 商は戻り値として、剰余はoutパラメータとして返されます。 これは除算演算子/
(VBでは\
)と剰余演算子%
(VBではMod
)の結果を同時に求めるのと同じ結果です。
累乗・平方根 (Pow, Sqrt)
累乗(べき乗)を求めるにはPowメソッド、平方根を求めるにはSqrtメソッドを使用します。 これらのメソッドは、引数・戻り値ともにDoubleです。 立方根(cbrt
)など、累乗根を直接求めるメソッドはMathクラスには用意されていませんが、Powメソッドに根の逆数(立方根なら⅓)を指定することによって累乗根を求めることができます。
VBには累乗演算子 ^ が用意されているので、これを用いることでも累乗・累乗根を求めることもできます。
ネイピア数eの累乗を求めるには、Expメソッドを使用することもできます。 なお、ネイピア数eはMath.Eフィールドを参照することで得られるので、わざわざ定数を定義する必要はありません。
ユークリッド距離・直角三角形の斜辺の長さ (hypot)
Mathクラスにはユークリッド距離/直角三角形の斜辺の長さを求めるhypot
関数のようなメソッドは用意されていないため、Powメソッド・Sqrtメソッドを組み合わせて計算する必要があります。
対数 (Log, Log10)
対数を求めるにはLogメソッドを使用します。 このメソッドは任意の底を指定することもできます。 logaxを求めるには、Math.Log(x, a)として呼び出します。 底を指定しない場合は、ネイピア数eを底とした自然対数lnとなります。 また、底を10とした常用対数log10xを求めるにはLog10メソッドを使用することができます。 これらのメソッドは、いずれも引数・戻り値ともにDoubleです。
Math.Log10メソッドを使うことで10進数数値の桁数を求めることができます。 Math.Log10メソッドやその他の手法で数の桁数を求める方法を数の桁数を求めるで解説しています。
2進対数(⌊log2n⌋・⌊lb n⌋)を求めたい場合、BitOperations.Log2メソッドを使うこともできます。
Logメソッド・Log10メソッドでは、0の対数を求めようとすると∞(無限大)が返されます。 底が1未満の場合は正の無限大(+∞)、底が1より大きい場合は負の無限大(-∞)が返されます。
三角関数・双曲線関数 (Sin, Cos, Tan, etc.)
三角関数・三角比を求める関数はそれぞれSinメソッド、Cosメソッド、Tanメソッドとして用意されています。 いずれも、角度の単位はラジアン(rad)です。 度数法・弧度法の変換(度⇄ラジアン)を行うメソッドは用意されていないので、必要に応じて変換処理を書く必要があります。 なお、円周率πはMath.PIフィールドを参照することで得られるので、わざわざ定数を定義する必要はありません。
座標変換などでよく使われる、xとyの二値から角度を求めるような場合にはAtan2メソッドを使用することができます。 Atan2メソッドは-π≦θ≦πの範囲で結果を返します。 また、Atanメソッドとは異なり、Atan2メソッドは引数の象限を考慮します。 そのため、引数y, xの値によってはAtan2メソッドとAtanメソッドで異なる結果となる場合があります。 また、Atan2メソッドでは、引数をy, xの順で指定する点に注意してください。
複素数を扱う場合はComplex構造体を使うことができます。 Complex構造体では直交形式・極座標形式の複素数を扱い、また相互に変換することもできます。 詳しくは複素数型を参照してください。
乱数
Mathクラスには乱数を取得するメソッドは用意されていません。 乱数が必要な場合はRandomクラスを使います。 詳しくは乱数を参照してください。