仅使用算术将值限制在最小值和最大值之间

时间:2018-11-07 09:20:05

标签: math max min plc clamp

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

我无法使用minmaxIF语句之类的功能。

假设我的范围为[1850, 1880],对于任何值< 1850,它都应显示1850。对于值> 1880,应显示1880。如果仅显示1850超出范围,也是可以接受的。

我尝试过:

x = (((x - xmax) % (xmax - xmin)) + (xmax - xmin)) % (xmax - xmin) + xmin 

但是对于小于xmin的值,它在范围的中间给出了不同的值。

3 个答案:

答案 0 :(得分:4)

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

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

    // number of bits in int
    // if your integer size is fixed, this is just a constant
    static const unsigned b = sizeof(int) * 8;

    // pow(2, b - 1)
    // again, a constant which can be pre-computed
    static const unsigned p = 1 << (b - 1);

    // use integer division to get top bit
    return (int)(u / p);
}

如果s < 0,则返回1;否则,返回0;否则,返回0。它可以用来计算绝对值

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

    // actual sign (+1 / -1)
    int s = 1 - 2 * b;

    // sign(v) * v = abs(v)
    return s * v;
}

所需的功能如下:

enter image description here

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

enter image description here

此函数形式可以计算为以下两个移位的绝对值函数的总和:

enter image description here

但是,结果函数的缩放比例为2;移至零会有所帮助,因为我们只需要除以2,然后移回原始最小值:

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

    // shift minimum to zero
    val = val - min;

    // blue function
    int blue = abs_arith(val);

    // green function
    int green = range - abs_arith(val - range);

    // add and divide by 2
    val = (blue + green) / 2;        

    // shift to original minimum
    return val + min;
}

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

答案 1 :(得分:0)

我在搞混的时候发现了这个。它仅适用于严格的正整数。尽管这对于meowgoesthedog的回答没有更多的限制,因为他还通过在末尾除以2来有效地将整数空间减半。它不使用mod。

import openpyxl

wb_10 = openpyxl.load_workbook('10.xlsx')
wb_11 = openpyxl.Workbook()

ws_10 = wb_10.active
ws_11 = wb_11.active

colE = ws_10['E']
colF = ws_10['F']
colG = ws_10['G']

for i in range(max(len(colE), len(colF), len(colG))):

    if colE[i].value == None: colE[i].value = 0
    if colF[i].value == None: colF[i].value = 0
    if colG[i].value == None: colG[i].value = 0

    ws_11.cell(row = i + 1, column = 8).value = colE[i].value + colF[i].value + colG[i].value

wb_11.save('11.xlsx')

答案 2 :(得分:-2)

我在Python中找到了此解决方案:

A = -1  # Minimum value
B = +1  # Maximum value
x = min(max(x, A), B)