代码之家  ›  专栏  ›  技术社区  ›  user2779346

如何划分256的无符号整数并舍入到更接近的值?[已关闭]

  •  6
  • user2779346  · 技术社区  · 11 年前

    我需要除以256,并将其四舍五入到更接近的值,例如,如果输入255,我想得到1,而不是0。现在我正在使用

    int x = 150;
    int z = MulDiv(x, 1, 256);
    

    但我认为这不是实现我目标的最佳方式,有人能给我更好的建议吗。

    4 回复  |  直到 11 年前
        1
  •  7
  •   ST3    11 年前

    使用此:

    unsigned int x = 150;
    unsigned int z = (x + 128) >> 8;
    

    128是中间值,所以加上这个值后,舍入有效,并且 256=2^8 所以你可以用移位运算代替除法。

    注意: 这种方式只适用于正值。

    如果你需要这个正值和负值,你需要这个:

    int x = -150;
    int z = (x >= 0 ? (x + 128) : (x - 128)) / 256;
    

    注意: 有符号值的比特移位有一些特定的,并且并不总是可以信任的,因此您不能使用此方法: int z = (x < 0) ? (x - 128) / 256 : (x + 128) >> 8;

        2
  •  4
  •   user529758 user529758    11 年前

    这将适用于正整数和负整数(以及零):

    int eps = x < 0 ? -128 : 128
    int y = (x + eps) / 256;
    

    强制性 -pedantic f[oo|ai]lsafe 版本:

    if (x < INT_MIN + 128 || x > INT_MAX - 128) {
        fputs("nasal demons!\n", stderr);
        abort();
    }
    
    int eps = x < 0 ? -128 : 128;
    int y = (x + eps) / 256;
    
        3
  •  1
  •   Paul R    11 年前

    要正确四舍五入到最接近的有符号值,可以执行以下操作:

    y = (x >= 0 ? (x + 128) : (x - 128)) / 256;
    
        4
  •  0
  •   fintelia    11 年前

    要正确处理非常大和非常小的值,可以使用

    int divideAndRound256(int x)
    {    
        if(x > INT_MAX - 128)
            return (x - 128) / 256 + 1;
        else if(x < INT_MIN + 128)
            return (x + 128) / 256 - 1;
        else if(x < 0)
            return (x - 128) / 256;
        else
            return (x + 128) / 256;
    }
    

    或者仅用于无符号值

    unsigned int divideAndRound256(unsigned int x)
    {    
        if(x > UINT_MAX - 128)
            return ((x - 128) >> 8) + 1;
        else
            return (x + 128) >> 8;
    }