如何“溢出”超出某个范围(例如30-100)的值

时间:2019-01-29 18:53:22

标签: c++ math struct

我创建了一个结构“ 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

3 个答案:

答案 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)。这里发生冲突!您不应该这样更改范围长度!