将此自定义轮转换为更加数学友好的解决方案

时间:2014-05-03 12:03:59

标签: c++ math

是的我想知道是否有办法将这种逻辑转换为更加数学友好的解决方案。首先,我想学习更多的数学,我很好奇两个是否有可能。

编辑是的,有些线路是多余的,或者不是类型安全等等,我们可以坚持手头的问题吗? :)

目标是将每个季度向下舍入到上一季度(如果不高于它)。

示例:

  

0.25 = 0,   0.27 = 0.25,   0.50 = 0.25,   0.52 = 0.50,   0.75 = 0.50,   0.78 = 0.75

float lulzRound(float value)
{
    int integer = (int)value;
    float start = value - (float)integer;
    float result;
    if(start < 0.25)
    {
        result = 0;
    }
    else if((start > 0.25) && (start <= 0.50))
    {
        result = 0.25;
    }
    else if((start > 0.50) && (start <= 0.75))
    {
        result = 0.50;
    }
    else if((start > 0.75) && (start < 1))
    {
        result = 0.75;
    }
    return (float)integer + result;
}

3 个答案:

答案 0 :(得分:1)

这样做的一种方法是:

return floor(value*4.0)*0.25;

这将0.25的值转换为0.25。如果您需要将其翻译为0.0,请使用:

return ceil(value*4.0)*0.25-0.25;

但请注意,这也会将0.0转换为-0.25。如果这不可接受,您可以使用:

return value < 0.25 ? 0 : ceil(value*4.0)*0.25-0.25;

或另一种选择:

return ceil(value*4.0)*0.25 - (fmod(value,1) ? 0.25 : 0);

这是一个简短的测试程序:

#include <iostream>
#include <cmath>

float round(float value)
{
    return ceil(value*4.0)*0.25 - 0.25;
}
int main()
{
    for (float i=0.0; i < 1.5; i+=0.05)
        std::cout << i << " ==> " << round(i) << '\n';
}

答案 1 :(得分:1)

float lulzRound(float value) {
    value *= 4.0f;
    int i = static_cast<int>(value);
    if(i > 0 && value == static_cast<float>(i)) {
        i--;
    }
    return static_cast<float>(i)*0.25f;
}

此代码适用于您指定的value >= 0。对于负数,它会做类似的事情。

答案 2 :(得分:0)

看起来你想要四舍五入到四分之一的单位。像这样:

int(value * 4) / 4.0     // [0.00, 0.25) -> 0.00
                         // [0.25, 0.50) -> 0.25
                         // [0.50, 0.75) -> 0.75
                         // [0.75, 1.00) -> 0.75

或者这个:

int(value * 4 - 1) / 4.0 // [0.00, 0.25) -> -.25
                         // [0.25, 0.50) -> 0.00
                         // [0.50, 0.75) -> 0.25
                         // [0.75, 1.00) -> 0.50