尽管存在 C++ 舍入错误,仍定义范围
Defining a range despite C++ rounding errors
给定下限、上限和步长,我想创建一个向量,其中包含从下限开始并逐步上升到上限的数字,由步长分隔。
例如较低 = 1.5,较高 = 6.0,步长 = 1.0:
return [1.5, 2.5, 3.5, 4.5, 5.5].
我的 C++ 代码目前是:
#include<iostream>
#include<armadillo>
using namespace std;
using namespace arma;
vec createArray( double lower, double upper, double step) {
int arrayLength = int ((upper - lower)/step + 1);
vec array(arrayLength);
for( int j = 0; j < arrayLength; j += 1 )
{
array(j) = lower + j*step;
}
return array;
}
理想情况下它应该可以正常工作,但舍入错误不断导致它输出错误的东西。例如,
int((pow(10,-7)-0)/pow(10,-9));
有时会输出 99 而不是 100,大概是因为 10^-7 被表示为 9.9999...9*10^-8。
我在想,有什么方法或技巧可以帮助我避免这些问题吗?
您应该 std::round
结果而不是截断。只要您的整数在您的浮点类型中可以准确表示,这至少会起作用。
就其价值而言,使用 std::vector
和 for
循环会更直接。
std::vector<double> createArray(double lower, double upper, double step)
{
std::vector<double> values;
for (double value = lower; value <= upper; value += step)
{
values.push_back(value);
}
return values;
}
这将使实际值尽可能接近正确的浮点值,而不会累积舍入误差。您仍然可以使用 <iomanip>
库将值输出到您喜欢的精度。
使用矢量,您不需要事先知道容器的大小。因此,只需创建一个循环,当您超过最大值时停止循环。这是一些伪代码。
vector<double> createVector(double minVal, double maxVal, double step)
{
vector<double> data;
while(minVal < maxVal){
data.push_back(minVal);
minVal += step;
}
return data;
}
给定下限、上限和步长,我想创建一个向量,其中包含从下限开始并逐步上升到上限的数字,由步长分隔。 例如较低 = 1.5,较高 = 6.0,步长 = 1.0: return [1.5, 2.5, 3.5, 4.5, 5.5].
我的 C++ 代码目前是:
#include<iostream>
#include<armadillo>
using namespace std;
using namespace arma;
vec createArray( double lower, double upper, double step) {
int arrayLength = int ((upper - lower)/step + 1);
vec array(arrayLength);
for( int j = 0; j < arrayLength; j += 1 )
{
array(j) = lower + j*step;
}
return array;
}
理想情况下它应该可以正常工作,但舍入错误不断导致它输出错误的东西。例如,
int((pow(10,-7)-0)/pow(10,-9));
有时会输出 99 而不是 100,大概是因为 10^-7 被表示为 9.9999...9*10^-8。
我在想,有什么方法或技巧可以帮助我避免这些问题吗?
您应该 std::round
结果而不是截断。只要您的整数在您的浮点类型中可以准确表示,这至少会起作用。
就其价值而言,使用 std::vector
和 for
循环会更直接。
std::vector<double> createArray(double lower, double upper, double step)
{
std::vector<double> values;
for (double value = lower; value <= upper; value += step)
{
values.push_back(value);
}
return values;
}
这将使实际值尽可能接近正确的浮点值,而不会累积舍入误差。您仍然可以使用 <iomanip>
库将值输出到您喜欢的精度。
使用矢量,您不需要事先知道容器的大小。因此,只需创建一个循环,当您超过最大值时停止循环。这是一些伪代码。
vector<double> createVector(double minVal, double maxVal, double step)
{
vector<double> data;
while(minVal < maxVal){
data.push_back(minVal);
minVal += step;
}
return data;
}