2つのdouble型変数の大小関係を調べる。
Compare two double-type variables.
◆形式(Format)
#include <doublemath.h>
inline int doublecmp(const double a,const double b)
◆引数(Arguments)
a
比較したい一方の実数。
One of the real numbers to be compared.
b
比較したいもう一つの実数。
The other one of the real numbers to be compared.
◆戻り値(Return value)
\(a > b\)のとき1
1 if \(a > b\)
\(a=b\)のとき0
0 if \(a=b\)
\(a < b\)のとき\(-1\)
\(-1\) if \(a < b\)
但し\(a\)と\(b\)が非常に近い値の場合は厳密に等しくなくても\(a=b\)と見なす。
詳しくは下記「判定方法」参照。
When \(a\) and \(b\) are very close to each other,
it is regarded that \(a=b\), even if they are not exactly equal.
For detail, see “Judgements” section below.
浮動小数点数では内部のビット表現の問題により、
本当は等しい2つの実数が僅かに異なる値を持つ場合がある。
例えば論理式
(1.0/3.0)∗3.0==1.0
はfalseとなる。
そこでこの関数では完全に\(a=b\)でなくとも
\(a\)と\(b\)の差がある閾値以下であれば\(a=b\)であると見なす。
その閾値のもとで\(a < b\)と見なされた場合は\(-1\)、
\(a=b\)と見なされた場合は0、
\(a > b\)と見なされた場合は1を返す。
Due to internal expressions of floating-point variables,
two real numbers which are equal
may have slightly different values to each other.
For example, a logical formula
(1.0/3.0)∗3.0==1.0
gives false.
In this function, \(a\) and \(b\) are regarded to be equal
if the difference between them is below a threshold level,
even if they are not exactly equal.
The return values are \(-1\), 0, and 1
if it is regarded that \(a < b\), \(a=b\), and \(a > b\), respectively,
based on comparisons of the differences to the threshold level.
\(a=b\)であると見なす基準としては
\[\begin{equation}
\frac{|a-b|}{\frac{|a|+|b|}{2}} < ZERO\_THRESHOLD
\label{eq.criterion}
\end{equation}\]
を用いている
(ZERO_THRESHOLDはmacro.hで定義されたマクロ)。
但し、0による割り算を防ぐため、
\(\frac{|a|+|b|}{2} \leq 0\)の場合は別扱いで0を返すようにしている。
これが成り立つのは厳密に\(a=b=0\)の場合だけであるので0を返して問題無い。
For a threshold to regard as \(a=b\), eq. (\ref{eq.criterion}) is used,
where ZERO_THRESHOLD is a macro defined in macro.h.
To avoid a division by 0,
the return value of this function is set to 0
in case of \(\frac{|a|+|b|}{2} \leq 0\).
This operation is validated by noticing that
the condition \(\frac{|a|+|b|}{2} \leq 0\) holds
only when strictly \(a=b=0\).
(\ref{eq.criterion})式の左辺の分母\(\frac{|a|+|b|}{2}\)は
\(a\),\(b\)の値そのものの大きさのスケールの目安と思えば良い。
例えば\(ZERO\_THRESHOLD=10^{-6}\)とした場合、
\(|a-b|\)が\(a\),\(b\)の大きさのスケールと比較しておおよそ6桁程度小さければ
事実上\(a=b\)と見なすというのが(\ref{eq.criterion})の意味するところである。
このような基準を用いているので
結果は\(a\)や\(b\)の値そのもののスケールには依存しない。
すなわち任意の正定数\(c\)について、
doublecmp(a,b)とdoublecmp(c*a,c*b)は同じ結果を返す。
The denominator of the left hand side of eq. (\ref{eq.criterion}),
i.e., \(\frac{|a|+|b|}{2}\),
can be regarded to be a measure of the scales of \(a\) and \(b\).
For example, when \(ZERO\_THRESHOLD=10^{-6}\),
eq. (\ref{eq.criterion}) means that
\(a\) and \(b\) are regarded to be equal
when the difference \(|a-b|\) is smaller than the scales of \(a\) and \(b\)
by a factor of \(\sim 10^6\).
Using this criterion, the result is independent of
the scales of \(a\) and \(b\);
doublecmp(a,b) and doublecmp(c*a,c*b) returns exactly the same values
for arbitrary positive constants \(c\).
例外として、\(a\)と\(b\)のどちらか片方が厳密に0.0の場合には
もう片方の絶対値がZERO_THRESHOLDよりも小さければ\(a=b\)と見なす。
例えば厳密に\(b=0.0\)の場合には
\(|a|<ZERO_THRESHOLD\)ならば\(a=b\)と見なす。
そうしないとif(doublecmp(a,0.0)==0){}のような判定文は
aにほんの僅かでも数値誤差があれば成り立たなくなるからである。
An exception is that
when one of \(a\) or \(b\) is exactly 0.0
and the absolute value of the other is less than ZERO_THRESHOLD,
\(a\) and \(b\) are regarded to be equal.
For example, when \(b\) is exactly 0.0
and \(|a|<ZERO_THRESHOLD\),
\(a\) is regarded to be equal to \(b\).
This is because otherwise
a very slight numerical error in \(a\) results in
a failure of judgement for if(doublecmp(a,0.0)==0){}.