Следующая программа с hexfloat
может показать вам детали.
К сожалению, извините, iomanip hexfloat
будет выглядеть как cout << hexfloat << diff;
, но при использовании флагов формата это комбинация ios::scientific | ios::fixed
.
current diff
0x0.p+0 0x1.47ae147ae147bp-7 <-- target
0x1.47ae147ae147bp-7 0x1.47ae147ae147bp-7
0x1.47ae147ae147bp-6 0x1.47ae147ae147bp-7
0x1.eb851eb851eb8p-6 0x1.47ae147ae147ap-7 similar
Посмотрите, как вывод шестнадцатеричного числа для target
и следующих двух строк заканчивается на b
. Затем следующий заканчивается на a
, который достаточно отличается, чтобы быть меньше target
, и выдает similar
.
В любом случае сохраните это как cpp-double-compare.cpp
и выполните:
make cpp-double-compare && echo 0.01 0.02 0.03 1.011 1.02 1.023 1.6 1.5 64.001 64.01 64 65 66 | ./cpp-double-compare
#include <cmath>
#include <iomanip>
#include <iostream>
using namespace std;
int main() {
double current = 0.0, last = 0.0;
constexpr int width = 30;
constexpr double target = 0.01;
constexpr ios::fmtflags fmt =
ios::scientific | ios::fixed | ios::left | ios::showbase | ios::showpoint;
cout << setw(width) << left << "current";
cout << setw(width) << left << "diff";
cout << endl;
cout.setf(fmt);
cout << setw(width) << 0.0;
cout << setw(width) << target << setw(0) << "<-- target";
cout << endl;
while (cin >> current) {
double diff = fabs(current - last);
cout << setw(width) << current;
cout << setw(width) << diff;
if (diff < target) {
cout << setw(0) << "similar";
}
cout << endl;
last = current;
}
return 0;
}