I have a C/C++ function checkt (FLT t) where FLT is the floating point precison set by the preprocessor that I want to use in a much bigger body of code to ensure that values passed to it are in the range [0,1]. It is often used in increasing a variable by fixed increments checkt trips an error when the argument is out of range. In this simple example I want to go from 0.0 to 1.0 in ten increments of 0.1. However since 0.1 is not represented perfectly as 0.1000000000 etc to the limit of precision and then I will attain exactly the value 1.0 at the end of the loop. The code snippet below works if FLT is set to double but not if it is set to float. I also append the output from both. The compiler is gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0.
#include <vector>
#include <iostream>
#define FLT double
void checkt (FLT t) {
if (t < FLT{0} || t > FLT{1}) {
std::cout << "t before error = " << t << std::endl;
throw std::runtime_error ("t out of range [0,1]");
}
}
int main(int argc, char **argv) {
FLT x = FLT{0.0};
FLT inc = FLT{0.1};
FLT y = FLT{1};
std::cout.precision(16);
std::cout << "x is " << x << "y is " << y << " inc is " << inc << std::endl;
for (int i=0; i<11; i++){
std::cout.precision(16);
std::cout << "x is " << x << std::endl;
checkt(x);
x += inc;
}
return 0;
}
Output with FLT=double x is 0y is 1 inc is 0.1
x is 0
x is 0.1
x is 0.2
x is 0.3
x is 0.4
x is 0.5
x is 0.6
x is 0.7
x is 0.7999999999999999
x is 0.8999999999999999
x is 0.9999999999999999
output with FLT = float is
y is 1 inc is 0.1000000014901161
x is 0
x is 0.1000000014901161
x is 0.2000000029802322
x is 0.300000011920929
x is 0.4000000059604645
x is 0.5
x is 0.6000000238418579
x is 0.7000000476837158
x is 0.8000000715255737
x is 0.9000000953674316
x is 1.00000011920929
t before error = 1.00000011920929
terminate called after throwing an inst
Aucun commentaire:
Enregistrer un commentaire