双可靠比较
Reliable comparison of double
我有一个公认的非常基本的问题:我需要比较 double
和 >=
类型的两个数字。但是,出于某种原因,对于我知道小于阈值的值,我的代码计算结果为真。
编辑:我的代码(错误发生在 Antenna
class 的 countTrig()
方法中):
#define k 0.0000000000000000000000138064852 // Boltzmann's constant
class Antenna{
vector<vector<double> > output;
int channels, smplrate, smpldur, samples, timethld;
double resistance, temp, bandwidth, lnanoise, lnagain, RMS;
public:
Antenna(
const int _channels, const int _smplrate, const int _smpldur,
const double _resistance, const double _temp, const double _bandwidth,
const double _lnanoise, const double _lnagain
){
channels = _channels; smplrate = _smplrate; smpldur = _smpldur;
resistance = _resistance; temp = _temp; bandwidth = _bandwidth;
lnanoise = _lnanoise; lnagain = _lnagain;
RMS = 2 * sqrt(4 * k * resistance * temp * bandwidth);
RMS *= lnagain * pow(10,(lnanoise/10));
samples = smplrate/smpldur;
timethld = 508; //= (1/smplrate) * 0.127;
}
void genThrml(int units);
void plotTrig(int timethld, double voltsthld);
void plotThrml();
int countTrig(double snrthld, int iter);
};
double fabs(double val){ if(val < 0){ val *= -1; } return val; }
void Antenna::genThrml(int units){
output.resize(samples, vector<double>(channels));
samples *= units;
gRandom->SetSeed(time(NULL));
for(int i = 0; i < samples; ++i){
for(int j = 0; j < channels; ++j){
output[i][j] = gRandom->Gaus(0,RMS);
}
}
}
void Antenna::plotThrml(){
//Filler
}
int Antenna::countTrig(double snrthld, int iter){
int count = 0;
int high = iter + timethld;
int low = iter - timethld;
if(low < 0){ low = 0; }
if(high > samples){ high = samples; }
for(int i = low; i < high; ++i){
for(int j = 0; j < channels; ++j){
if(output[i][j] >= snrthld) count++; std::cout << output[i][j] << " " << snrthld << "\n";
}
}
if(iter >= 3) return 1;
else return 0;
}
void Antenna::plotTrig(int timethld, double voltsthld){
double snrthld = voltsthld / RMS;
for(int i = 0; i < samples; ++i){
for(int j = 0; j < channels; ++j){
countTrig(snrthld, i);
}
}
}
int main(){
Antenna test(20,4000,1,50,290,500000000,1.5,60);
test.genThrml(1);
test.plotTrig(400,0.0005);
return 0;
}
阈值为 0.147417,我得到这样的输出:
0.0014238
-0.00187276
我相信我理解问题所在(除非我犯了一些明显的错误但没有发现),并且我理解浮点错误、精度等背后的原因。我不,但是,知道这里的最佳实践是什么。什么是好的解决方案?我怎样才能可靠地比较 double
类型的值?这将用于对值的精确性和比较的可靠性非常重要的应用程序。
编辑:一个更小的例子:
int countTrig(double snrthld, int iter, vector<vector<double> > output, int timethld){
int count = 0;
int high = iter + timethld;
int low = iter - timethld;
if(low < 0){ low = 0; }
if(high > 3){ high = 3; }
for(int i = low; i < high; ++i){
for(int j = 0; j < 3; ++j){
if(fabs(output[i][j]) >= snrthld) count++; std::cout << output[i][j] << " " << snrthld << "\n";
}
}
if(iter >= 3) return 1;
else return 0;
}
void plotTrig(int timethld, double snrthld){
vector<vector<double> > output = {{0.000028382, -0.0028348329, -0.00008573829},
{0.183849939, 0.9283829020, -0.92838200021},
{-0.00292889, 0.2399229929, -0.00081009189}};
for(int i = 0; i < 3; ++i){
for(int j = 0; j < 3; ++j){
countTrig(snrthld, i, output, timethld);
}
}
}
int main(){
plotTrig(1,0.1);
return 0;
}
你打错了。
if(output[i][j] >= snrthld) count++; std::cout << output[i][j] << " " << snrthld << "\n";
这一行的意思是
if(output[i][j] >= snrthld)
count++;
std::cout << output[i][j] << " " << snrthld << "\n";
又名
if(output[i][j] >= snrthld)
{
count++;
}
std::cout << output[i][j] << " " << snrthld << "\n";
你想要:
if(output[i][j] >= snrthld)
{
count++;
std::cout << output[i][j] << " " << snrthld << "\n";
}
我有一个公认的非常基本的问题:我需要比较 double
和 >=
类型的两个数字。但是,出于某种原因,对于我知道小于阈值的值,我的代码计算结果为真。
编辑:我的代码(错误发生在 Antenna
class 的 countTrig()
方法中):
#define k 0.0000000000000000000000138064852 // Boltzmann's constant
class Antenna{
vector<vector<double> > output;
int channels, smplrate, smpldur, samples, timethld;
double resistance, temp, bandwidth, lnanoise, lnagain, RMS;
public:
Antenna(
const int _channels, const int _smplrate, const int _smpldur,
const double _resistance, const double _temp, const double _bandwidth,
const double _lnanoise, const double _lnagain
){
channels = _channels; smplrate = _smplrate; smpldur = _smpldur;
resistance = _resistance; temp = _temp; bandwidth = _bandwidth;
lnanoise = _lnanoise; lnagain = _lnagain;
RMS = 2 * sqrt(4 * k * resistance * temp * bandwidth);
RMS *= lnagain * pow(10,(lnanoise/10));
samples = smplrate/smpldur;
timethld = 508; //= (1/smplrate) * 0.127;
}
void genThrml(int units);
void plotTrig(int timethld, double voltsthld);
void plotThrml();
int countTrig(double snrthld, int iter);
};
double fabs(double val){ if(val < 0){ val *= -1; } return val; }
void Antenna::genThrml(int units){
output.resize(samples, vector<double>(channels));
samples *= units;
gRandom->SetSeed(time(NULL));
for(int i = 0; i < samples; ++i){
for(int j = 0; j < channels; ++j){
output[i][j] = gRandom->Gaus(0,RMS);
}
}
}
void Antenna::plotThrml(){
//Filler
}
int Antenna::countTrig(double snrthld, int iter){
int count = 0;
int high = iter + timethld;
int low = iter - timethld;
if(low < 0){ low = 0; }
if(high > samples){ high = samples; }
for(int i = low; i < high; ++i){
for(int j = 0; j < channels; ++j){
if(output[i][j] >= snrthld) count++; std::cout << output[i][j] << " " << snrthld << "\n";
}
}
if(iter >= 3) return 1;
else return 0;
}
void Antenna::plotTrig(int timethld, double voltsthld){
double snrthld = voltsthld / RMS;
for(int i = 0; i < samples; ++i){
for(int j = 0; j < channels; ++j){
countTrig(snrthld, i);
}
}
}
int main(){
Antenna test(20,4000,1,50,290,500000000,1.5,60);
test.genThrml(1);
test.plotTrig(400,0.0005);
return 0;
}
阈值为 0.147417,我得到这样的输出:
0.0014238
-0.00187276
我相信我理解问题所在(除非我犯了一些明显的错误但没有发现),并且我理解浮点错误、精度等背后的原因。我不,但是,知道这里的最佳实践是什么。什么是好的解决方案?我怎样才能可靠地比较 double
类型的值?这将用于对值的精确性和比较的可靠性非常重要的应用程序。
编辑:一个更小的例子:
int countTrig(double snrthld, int iter, vector<vector<double> > output, int timethld){
int count = 0;
int high = iter + timethld;
int low = iter - timethld;
if(low < 0){ low = 0; }
if(high > 3){ high = 3; }
for(int i = low; i < high; ++i){
for(int j = 0; j < 3; ++j){
if(fabs(output[i][j]) >= snrthld) count++; std::cout << output[i][j] << " " << snrthld << "\n";
}
}
if(iter >= 3) return 1;
else return 0;
}
void plotTrig(int timethld, double snrthld){
vector<vector<double> > output = {{0.000028382, -0.0028348329, -0.00008573829},
{0.183849939, 0.9283829020, -0.92838200021},
{-0.00292889, 0.2399229929, -0.00081009189}};
for(int i = 0; i < 3; ++i){
for(int j = 0; j < 3; ++j){
countTrig(snrthld, i, output, timethld);
}
}
}
int main(){
plotTrig(1,0.1);
return 0;
}
你打错了。
if(output[i][j] >= snrthld) count++; std::cout << output[i][j] << " " << snrthld << "\n";
这一行的意思是
if(output[i][j] >= snrthld)
count++;
std::cout << output[i][j] << " " << snrthld << "\n";
又名
if(output[i][j] >= snrthld)
{
count++;
}
std::cout << output[i][j] << " " << snrthld << "\n";
你想要:
if(output[i][j] >= snrthld)
{
count++;
std::cout << output[i][j] << " " << snrthld << "\n";
}