2つの二重配列、たとえばAとBがあります。それらの結果を有効数字7桁と比較したいと思います。比較するために以下は正しいでしょうか?
k = pow(10,7);
for(...)
{
if(((int)A[i]*k)!=((int)B[i]*k))
{
...
}
}
2つの二重配列、たとえばAとBがあります。それらの結果を有効数字7桁と比較したいと思います。比較するために以下は正しいでしょうか?
k = pow(10,7);
for(...)
{
if(((int)A[i]*k)!=((int)B[i]*k))
{
...
}
}
ダブルスを比較するには、次のようなものを使用できます。
bool fequal(double a, double b)
{
return fabs(a-b) < epsilon;
}
ここから撮影。
fabs
参照。
ただし、潜在的な落とし穴を必ず理解してください。
いいえ、これは機能しません。
型キャスト演算子は、乗算演算子よりも優先されます。これは、A[i]
とB[i]
が1e7で乗算される前に整数にキャストされる(そして切り捨てられる)ことを意味します。2.25と2.5は、最終的にコードと同じになります。かっこで乗算を入れることで、これを修正できます。(int)(A[i]*k)
また、丸めではなく切り捨てに依存しているため、(期待する内容によっては)誤った結果になる可能性があります。1.0e-7
と1.9e-7
は等しくなりますが(1 == 1
)、1.9e-7
とは等しく2.1e-7
なりません(1 != 2
)。希望する動作で適切に丸められる関数を見つけることをお勧めします。
また、比較では有効数字は処理されず、指数の値が変更されるだけです。上記の例では、有効数字は2桁しかありませんが、指数の値が-7であるため、コードはそれらの数字の1つのみを比較します。
これがあなたが望むことをするいくつかのコードです:
//create integer value that contains 7 significant digits of input number
int adjust_num(double num) {
double low_bound = 1e7;
double high_bound = low_bound*10;
double adjusted = num;
int is_negative = (num < 0);
if(num == 0) {
return 0;
}
if(is_negative) {
adjusted *= -1;
}
while(adjusted < low_bound) {
adjusted *= 10;
}
while(adjusted >= high_bound) {
adjusted /= 10;
}
if(is_negative) {
adjusted *= -1;
}
//define int round(double) to be a function which rounds
//correctly for your domain application.
return round(adjusted);
}
...
if(adjust_num(A[i]) == adjust_num(B[i])) {
...
}
はい。ただし、1つの変更を加える必要があります。(int)(A [i] * k)を試して、乗算が最初に実行されることを確認してください。
お役に立てれば。
2つの浮動小数点値を使用して、それらが理想的に持つ値が等しいかどうかを判断する場合、正確に計算された値が同等。そのような限界がある場合は、次のようなテストを実行できます。「2つの数値が誤差限界よりも近い場合は、それらを等しいものとして受け入れます。」エラーバウンドは、単一の絶対数であるか、値の1つの大きさに相対的な数であるか、または値の他の関数である可能性があります。
ただし、答えるべき別の質問があります。正確に計算された値が等しくない場合でも、上記のテストでは、値が等しいものとして受け入れられる場合があります(2つの計算された値が近いため、場合によっては等しいため)。したがって、正確に計算された数値が等しくなくても、互いに近い計算値を等しいものとして受け入れることが問題を引き起こすかどうかを知っています。答えが「はい」の場合、上記のテストは問題を引き起こす同じ数として受け入れられることがあり、このテストを使用することはできません。エラーを減らすために、別の方法で計算を実行する必要がある場合があります。
一見小さなしきい値を作成して使用するようにアドバイスされることがよくあります。これはずさんなプログラミングであり、エンジニアリングではありません。
余談ですが、決して書いてはいけませんpow(10, 7)
。書く1e7
。これにより、関数呼び出しでエラーが発生する可能性が回避され、不要な関数呼び出しが完全に回避される可能性があります。