首先让我说我已经检查了相关主题 问题是我想用小数步长制作一个for循环 我已经准备了波纹管代码来解决问题,但是它没有使用上面提到的步长
生成准确的数字 float b;
for ( double a=-0.2; a<=0.2 ; a+=0.01)// a = landa with an increment of 0.1
{
b = a * 100.0;
a = ((int)b) / 100.0;
}
我想要的是在每次迭代中都有一个准确的数字,但是因为变量被定义为一个双倍,它接近它必须的值。( - 0.20000000001,-0.19000000002,....) 请让我知道如何解决这个问题&amp;代码有什么问题吗?
答案 0 :(得分:14)
而不是:
for (double a = -0.2; a <= 0.2; a += 0.01)
{
...
}
使用整数循环索引并计算循环内的相应浮点值,例如
for (int i = -20; i <= 20 ; ++i) // a = -0.2 to 0.2 step 0.01
{
const double a = i / 100.0;
...
}
答案 1 :(得分:2)
要使用精确小数进行计算,您可以使用像bdldfp::Decimal64这样的十进制浮点类:十进制浮点不要使用基数2哪些计算机擅长计算,而是基数10。结果他们的处理速度较慢(使用IBM的decNumber当前的实现并不是很好,但正在纠正使用英特尔的实现)。作为回报,十进制计算是准确的:
using namespace BloombergLP;
bdldfp::Decimal64 a(BDLDFP_DECIMAL64_DD(-0.2));
bdldfp::Decimal64 add(BDLDFP_DECIMAL64_DD(0.01));
bdldfp::Decimal64 end(BDLDFP_DECIMAL64_DD(0.2));
for (; a <= end; a += add) {
std::cout << a << '\n';
}
可以使用C ++ 11特性(例如,使用_DD
作为文字后缀)来实现更好的实现,但它也适用于C ++ 03编译器。我正致力于将十进制浮点类添加到C ++标准中(here是该提案的最新版本。)
使用二进制浮点时,例如double
,您无法准确表示值。您可能会获得基于整数进行迭代的最接近的值,并在每次迭代中适当地划分:
for (int a(-20); a <= 20; ++a) {
std::cout << (a / 100.0) << '\n';
}
直接使用double
并在每次迭代中添加0.01
时会出现一些舍入错误,这会增加先前值的不准确性。
答案 2 :(得分:1)
沿着这些方向使用:
double min = -0.2;
double max = +0.2;
int N = 40;
for(int i=0; i<=N; i++) {
double a = min + static_cast<double>(i)*((max - min)/static_cast<double>(N));
double b = a * 100.0;
...
}
答案 3 :(得分:1)
这句话也是一个潜在的问题:
a = ((int)b) / 100.;
因为(int)b将b截断为零。例如,如果b == 101.9999999999,那么(int)b将产生101(而不是102)。要坚持原始概念,请尝试以下方法:
double a;
int b;
for(a = -.2; a <= .2; a += .01){
b = (int)(a*100. + ((a < -0.005)? -.5 : .5));
a = (double)b / 100.;
}
注意,(a <-005)是对负数a的检查,误差幅度为步进率的1/2。
正如其他人发布的那样,使用整数表示循环并设置&#39; a&#39;基于整数将是一个更好的解决方案。