舍入一个整数,使其乘以浮点数返回整数

时间:2017-06-01 16:03:28

标签: c++ algorithm math scaling

我正在处理图像缩放应用程序,我给出了缩放比例和矩形。我需要将矩形与比率相乘,但也要确保生成的矩形仅由整数组成(即没有浮点数)。如果没有,我想扩展源矩形,以便上述条件为真。

此刻,我强行强迫它(下面的代码)。但我非常确定使用聪明的数学方法可以做到这一点。

RECT AdjustRectWholeNumber(RECT SrcRect, float ratio)
{
    RECT adjustedRect = SrcRect;
    while (!isWholeNumber(adjustedRect.left * ratio))
    {
        adjustedRect.left--;
    }
    while (!isWholeNumber(adjustedRect.top * ratio))
    {
        adjustedRect.top--;
    }
    while (!isWholeNumber(adjustedRect.right * ratio))
    {
        adjustedRect.right++;
    }
    while (!isWholeNumber(adjustedRect.bottom * ratio))
    {
        adjustedRect.bottom++;
    }
    return adjustedRect;
}

示例:给定rect(78,188,1068,790)和比率1.25,它应该返回(76,188,1068,792)

推理:如果我乘以(78,188,1068,790)乘以1.25,它会给我(97.5,188,1068,987.5)。这不是理想的,因为如果我舍入(向上或向下)缩放的矩形,我将失去精度,这在屏幕上显示为小的损坏伪像。就像我们扩展源矩形一样,在乘以缩放因子后,我们得到所有整数,没有精度丢失,因此没有看到损坏。

注意:保证缩放比率能够产生整数

感谢任何帮助!

编辑:根据要求添加isWholeNumber的代码

bool isWholeNumber(float f)
{
    if (floor(f) == f)
        return true;
    return false;
}

为了澄清,让我们假设我将获得的唯一比率是(1.25,1.5,1.75,2.0,2.25)

1 个答案:

答案 0 :(得分:2)

我认为一般来说,你所说的问题都有一个很好的解决方案。并非所有“好”分数都具有精确表示为浮点数(例如4/3不具有)。通常,精确表示仅适用于功率为2作为分母的那些分数。如果您尝试使用float逼近“坏”分数,您将获得一个分母约为2^-20的分数,即大约10^-6拟合,这是没有意义的。因此,显而易见的建议是使用一些显式自定义类型来表示分数作为显式(整数)分母和分母。如果你对分母有明确的价值,那么任务变得微不足道。或者,如果您确定

  

我将获得的唯一比率是(1.25,1.5,1.75,2.0,2.25)

你可以有一个匹配值的简单函数,并说明分母是12还是4。如果你有更多可能的值,但所有分数都有2分母的幂,你也可以考虑使用frexp/frexpf来获得指数(分母的2的幂)

所以现在当你有一个整数分母时,一切都很简单:你只需要找到一个可被它整除的数字。您可以使用整数除法和乘法(假设您的值为正):

int roundDown(int value, int denominator) {
    return (value / denominator) * denominator;
}

int roundUp(int value, int denominator) {
    return ((value + denominator - 1) / denominator) * denominator;
}