Algorithm 如何使用mod运算符包装数字

Algorithm 如何使用mod运算符包装数字,algorithm,modulo,Algorithm,Modulo,不确定这是否可行,但是否有一种自动方法,使用mod或类似的工具,自动更正错误的输入值?例如: If r>255, then set r=255 and if r<0, then set r=0 如果r>255,则设置r=255和 如果r你能做些类似的事情吗-- 那么: r = std:max(0, std::min(r, 255)); 根据您的硬件以及解释器处理INT的方式,您可以执行以下操作: 假设一个无符号整数是16位(以保持掩码短): 如果int是32位,那么在位掩码的开头

不确定这是否可行,但是否有一种自动方法,使用mod或类似的工具,自动更正错误的输入值?例如:

If r>255, then set r=255 and
if r<0, then set r=0
如果r>255,则设置r=255和

如果r你能做些类似的事情吗--

那么:

r = std:max(0, std::min(r, 255));

根据您的硬件以及解释器处理INT的方式,您可以执行以下操作:

假设一个无符号整数是16位(以保持掩码短):

如果int是32位,那么在位掩码的开头还需要16个零


在按位AND之后,r的最大值为255。根据硬件的不同,给定一个小于零的值,无符号int可能会做一些奇怪的事情。我相信这种情况已经由位掩码处理(至少在我使用的硬件上)。如果没有,你可以做
r=min(r,0)首先。

以下函数将输出您要查找的内容:

 f(x) = (510*(1 + Sign[-255 + x]) + x*(1 + Sign[255 - x])*(1 + Sign[x]))/4
如图所示:


我在处理图像时也遇到了类似的问题。对于某些特殊值(如0和255),可以使用以下不可移植方法:

static inline int trim_8bit(unsigned i){
    return 0xff & ((i | -!!(i & ~0xff))) + (i >> 31);
    // where "0xff &" can be omitted if you return unsigned char
};
在实际情况下,夹紧必须很少执行,以便您可以编写

static inline unsigned char trim_8bit_v2(unsigned i){   
    if (__builtin_expect(i & ~0xFF, 0)) // it's for gcc, use __assume for MSVC
        return (i >> 31) - 1; 
    return i;
};


为了确定哪一个是最快的,测量一下。

那是行不通的
R
将始终为零或负数。最小值和最大值的计算方法错误。结果总是0。即使这样做有效,也不能真正回答问题。MAX和MIN都有条件,询问者试图避免这些条件。@Kdoto:我不确定标准指定了MIN/MAX的实现方式。OP寻求一种巧妙的数学方法。最小值/最大值是相对标准的数学函数。我怀疑这个问题是关于速度的,更多的是关于美学的。对于未来的回答者,我认为提问者正在尝试无条件地这样做。这意味着不允许调用MAX或MIN函数。我想可能会有一种很酷的数学方法,但我想任何独特的快捷方式都是有效的,即使MIN和MAX几乎都是条件函数。你只是好奇,还是在寻找速度增益或更好的美学效果?Wrap是不同的。这种操作称为饱和或钳位。我同意@ruslik。问题的标题是否可以更改为删除“wrap”一词,该词可以使用模作为优雅的数学解?否则,像我这样的人会一直到这里来寻找完整的答案。你是在假设问题中没有任何意义。你不知道这个数字是如何用二进制来描述的,我想是的。这是迄今为止我所看到的唯一一个能带来效率提升而不仅仅是美学提升的答案。所以我觉得值得一提。你是对的,我假设r是以有限的、可屏蔽的形式存储的,这是我见过的所有问题的情况。我确实在我的回答中写了“假设一个无符号整数是16位的:)如果这让你感觉更好,你可以将同样的逻辑应用到一个存储有无限多个数字的数字上,只要你知道这个数字表示为什么结构,并且可以对这个数字形成一个掩码。@Kdoto正如你所知。不是我否决了你的帖子。@stefan,谢谢。我没想到你会这么做。那么你是如何实现Sign:-)@stefan的呢?如果它不是一个原语的话,那么有很多方法可以做到这一点。例如,符号[x]=x/Abs[x](代表x!=0)@belisarius我同意Kdoto>D,但有Mathematica在手,我想我们可以坐在这里整整一千年;-)@stefan有那么糟糕吗D@belisariusMathematica?的确如此。我有一个巨大的PDF,我真的不知道从一些讨厌的迭代积分中可以找到什么。当Mathematica用“\[Pi]”作为答案时,我死了一个月。
 f(x) = (510*(1 + Sign[-255 + x]) + x*(1 + Sign[255 - x])*(1 + Sign[x]))/4
static inline int trim_8bit(unsigned i){
    return 0xff & ((i | -!!(i & ~0xff))) + (i >> 31);
    // where "0xff &" can be omitted if you return unsigned char
};
static inline unsigned char trim_8bit_v2(unsigned i){   
    if (__builtin_expect(i & ~0xFF, 0)) // it's for gcc, use __assume for MSVC
        return (i >> 31) - 1; 
    return i;
};