関数doublecmp マニュアル

(The documentation of function doublecmp)

Last Update: 2021/12/27


◆機能・用途(Purpose)

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)

但しabが非常に近い値の場合は厳密に等しくなくても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.


◆使用例(Example)

double a,b;
if(doublecmp(a,b)>0){
    printf("a>b\n");
}else if(doublecmp(a,b)==0){
    printf("a=b\n");
}else{
    printf("a<b\n");
}


◆判定方法(Judgements)

浮動小数点数では内部のビット表現の問題により、 本当は等しい2つの実数が僅かに異なる値を持つ場合がある。 例えば論理式
    (1.0/3.0)∗3.0==1.0
はfalseとなる。 そこでこの関数では完全にa=bでなくとも abの差がある閾値以下であればa=bであると見なす。 その閾値のもとでa<bと見なされた場合は1a=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であると見なす基準としては (1)|ab||a|+|b|2<ZERO_THRESHOLD を用いている (ZERO_THRESHOLDはmacro.hで定義されたマクロ)。 但し、0による割り算を防ぐため、 |a|+|b|20の場合は別扱いで0を返すようにしている。 これが成り立つのは厳密にa=b=0の場合だけであるので0を返して問題無い。
For a threshold to regard as a=b, eq. (1) 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 |a|+|b|20. This operation is validated by noticing that the condition |a|+|b|20 holds only when strictly a=b=0.

(1)式の左辺の分母|a|+|b|2a,bの値そのものの大きさのスケールの目安と思えば良い。 例えばZERO_THRESHOLD=106とした場合、 |ab|a,bの大きさのスケールと比較しておおよそ6桁程度小さければ 事実上a=bと見なすというのが(1)の意味するところである。 このような基準を用いているので 結果はabの値そのもののスケールには依存しない。 すなわち任意の正定数cについて、 doublecmp(a,b)とdoublecmp(c*a,c*b)は同じ結果を返す。
The denominator of the left hand side of eq. (1), i.e., |a|+|b|2, can be regarded to be a measure of the scales of a and b. For example, when ZERO_THRESHOLD=106, eq. (1) means that a and b are regarded to be equal when the difference |ab| is smaller than the scales of a and b by a factor of 106. 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.

例外として、abのどちらか片方が厳密に0.0の場合には もう片方の絶対値がZERO_THRESHOLDよりも小さければa=bと見なす。 例えば厳密にb=0.0の場合には |a|<ZEROTHRESHOLDならば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|<ZEROTHRESHOLD, 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){}.