仅使用算术限制min和max之间的值


IP地址
2025-03-16 12:19:49 (23天前)


是否可以仅使用算术限制给定范围内的值,最小值和最大值之间?也就是说,+ - x /和%?

我无法使用min,max和IF语句等函数。

我们假设……

2 条回复
  1. 0# 镜乃Kagamino | 2019-08-31 10-32



    如果您知道整数类型的大小,则可以使用整数除法提取其符号位(假设为二进制补码):




    1. // Example in C
      int sign_bit(int s)
      {
      // cast to unsigned (important)
      unsigned u = (unsigned)s;

    2. // number of bits in int
    3. // if your integer size is fixed, this is just a constant
    4. static const unsigned b = sizeof(int) * 8;
    5. // pow(2, b - 1)
    6. // again, a constant which can be pre-computed
    7. static const unsigned p = 1 << (b - 1);
    8. // use integer division to get top bit
    9. return (int)(u / p);
    10. }

    11. </code>


    如果,则返回1

    s < 0

    否则为0;它可以用来计算

    绝对值





    1. int abs_arith(int v)
      {
      // sign bit
      int b = sign_bit(v);

    2. // actual sign (+1 / -1)
    3. int s = 1 - 2 * b;
    4. // sign(v) * v = abs(v)
    5. return s * v;
    6. }

    7. </code>




    所需的功能如下所示:








    首先将最小值移至零是有用的:








    该函数形式可以计算为两个移位的和

    绝对值

    功能如下:








    然而,得到的函数按比例缩放2倍;转移到零有助于此处,因为我们只需要除以2,然后转回原来的最小值:




    1. // Example in C
      int clamp_minmax(int val, int min, int max)
      {
      // range length
      int range = max - min;

    2. // shift minimum to zero
    3. val = val - min;
    4. // blue function
    5. int blue = abs_arith(val);
    6. // green function
    7. int green = range - abs_arith(val - range);
    8. // add and divide by 2
    9. val = (blue + green) / 2;        
    10. // shift to original minimum
    11. return val + min;
    12. }

    13. </code>


    该解决方案虽然满足问题的要求,但仅限于有符号整数类型(以及允许整数溢出的语言 - 我不确定如何在例如Java中克服这种情况)。


登录 后才能参与评论