我创建了一个结构“ Range”,其中包含两个名为min和max的整数。我正在尝试编写一个函数,该函数接受一个整数,如果超出范围,则将其溢出。
例如,如果我有一个范围1-100
并传递了105
,则返回值应为5
。
当我尝试溢出时,代码可以正常工作大于最大值但小于最小值的值时发生意外行为,并且我找不到正确的公式。
这是我正在使用的范围结构
{{2 }}这是我在下面的代码中使用的函数声明
struct Range
{
int min;
int max;
};
这里是值超出范围时的代码。max
{{2 }}这是值小于范围的代码。min
int overflowRange(const Range &range, int n)
当if (n > range.max)
{
double dist = static_cast<double>(n - range.max);
double length = (range.max - range.min) + 1;
//How many ranges away is n ?
double numRanges = std::ceil(dist / length);
return static_cast<int>(n - (length * numRanges));
}
或else if (n < range.min) //n is the tested integer
{
double dist = static_cast<double>(range.min - n);
double length = (range.max - range.min);
//How many ranges away is n ?
int numRanges = static_cast<int>(dist / length);
return static_cast<int>((range.min + length) - (dist - (length * numRanges)));
}
时,返回值有时超出范围
例如:如果范围为dist / length == 1
,整数为length * numRanges == dist
,我希望返回值为30-100
,但实际上是-40
答案 0 :(得分:2)
您可以使用整数数学来解决这个问题:
struct Range
{
int min;
int max;
};
int overflowRange(const Range &range, int n)
{
int size = range.max - range.min;
n -= range.min;
n %= size;
if (n < 0)
{
n += size;
}
n += range.min;
return n;
}
答案 1 :(得分:1)
当值小于最小值时,隐式地使用最大值作为基准面可能是您的问题。如果将return语句更改为以下内容,则它应该起作用。
return static_cast<int>(n + length*numRanges); // similar to above range case
您可以简化数学逻辑,只需在照顾数据的同时让数学负责方向。
int numRanges = 0;
double length = range.max - range.min; // you could make this a function on Range
if (n < range.min)
{
double dist = n - range.min;
numRanges = std::floor(dist/length);
}
else if (n > range.max)
{
double dist = n - range.max;
numRanges = std::ceil(dist/length);
}
else
{
numRanges = 0;
}
return value - numRanges * length;
我用[-40,29,30,100,101,170]测试了该算法,结果分别为[30,99,30,100,31,100]。
答案 2 :(得分:1)
根据您的示例,给定范围1-100,当您输入105时,返回值应为5,在101-200范围内将100用作0。这意味着范围的长度为100但不是99,因为您实际上溢出了100个数字。 因此,您在这里使用length =(range.max-range.min)+ 1,而不是(range.max-range.min)。
但是,当传递值低于最小值时,您的“预期行为”是什么?例如,给定范围30-100,当您传递29时应该返回哪个数字?根据您的例外情况“如果范围是30-100,并且整数是-40,我希望返回值是30”,那么在给定29的情况下,它应该返回30+(29-(-40))= 99 30和100代表相同的数字。因此,在此示例中,您溢出了69个数字,但没有溢出70个数字,这意味着您在此处使用length =(range.max-range.min)。这里发生冲突!您不应该这样更改范围长度!