重新使用移位实现模? [英] re implement modulo using bit shifts?

查看:190
本文介绍了重新使用移位实现模?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在写一些code非常有限的系统,其中Mod运算速度非常慢。在我的codeA模需要每秒要使用约180倍,我想,删除它尽可能多地将显著增加我的code的速度,现在我的一个主循环不会运行在周期1/60秒,因为它应该。我想知道,如果只使用移位喜欢的是可能的乘法和除法有可能重新实现模。因此,这里是我的code到目前为止,在C ++(如果我可以执行使用汇编的话会更好模)。如何删除不使用乘除模?

I'm writing some code for a very limited system where the mod operator is very slow. In my code a modulo needs to be used about 180 times per second and I figured that removing it as much as possible would significantly increase the speed of my code, as of now one cycle of my mainloop does not run in 1/60 of a second as it should. I was wondering if it was possible to re-implement the modulo using only bit shifts like is possible with multiplication and division. So here is my code so far in c++ (if i can perform a modulo using assembly it would be even better). How can I remove the modulo without using division or multiplication?

    while(input > 0)
{
    out = (out << 3) + (out << 1);
    out += input % 10;

    input = (input >> 8) + (input >> 1);
}

编辑:其实我意识到我需要做的方式超过180次每秒。看到,因为输入的值可以是一个非常大的数量最多为40个数字。

Actually I realized that I need to do it way more than 180 times per second. Seeing as the value of input can be a very large number up to 40 digits.

推荐答案

您可以使用的简单的位操作,​​走的是值的功率为2的模(除数)做什么(股息)通过与除数-1 AND'ing的吧。举几个例子:

What you can do with simple bitwise operations is taking a power-of-two modulo(divisor) of the value(dividend) by AND'ing it with divisor-1. A few examples:

unsigned int val = 123; // initial value
unsigned int rem;

rem = val & 0x3; // remainder after value is divided by 4. 
                 // Equivalent to 'val % 4'
rem = val % 5;   // remainder after value is divided by 5.
                 // Because 5 isn't power of two, we can't simply AND it with 5-1(=4). 

为什么它的工作原理?让我们考虑值123这是一个有点模式 1111011 ,然后除数4,其中有位模式的 00000100 。正如我们所知道现在,除数必须是乘方的两(如4),我们需要一个(从4到十进制3)递减它这产生我们的位模式 00000011 。我们按位与后两个原始123和3中,所得到的位模式将是 00000011 。这原来是十进制3。为什么我们需要功率为2的除数的原因是,一旦我们减一他们,我们得到了所有设置为 1 少显著位,其余均为 0 。一旦我们这样做按位与,它抵消了从原来的值更显著位,留给我们除以除数原值的根本其余部分。

Why it works? Let's consider a bit pattern for the value 123 which is 1111011 and then the divisor 4, which has the bit pattern of 00000100. As we know by now, the divisor has to be power-of-two(as 4 is) and we need to decrement it by one(from 4 to 3 in decimal) which yields us the bit pattern 00000011. After we bitwise-AND both the original 123 and 3, the resulting bit pattern will be 00000011. That turns out to be 3 in decimal. The reason why we need a power-of-two divisor is that once we decrement them by one, we get all the less significant bits set to 1 and the rest are 0. Once we do the bitwise-AND, it 'cancels out' the more significant bits from the original value, and leaves us with simply the remainder of the original value divided by the divisor.

但是,应用特定像这样的东西任意除数是行不通的,除非你知道你的除数事先(在编译时,甚则需要特定的除数codepaths) - 解决它运行时是不可行,尤其不要在你的情况下的性能问题。

However, applying something specific like this for arbitrary divisors is not going to work unless you know your divisors beforehand(at compile time, and even then requires divisor-specific codepaths) - resolving it run-time is not feasible, especially not in your case where performance matters.

也有<一个href=\"http://stackoverflow.com/questions/980702/efficient-cycles-wise-algorithm-to-compute-modulo-25\">a $ P $涉及这可能对来自不同角度的事有趣的信息主题 pvious问题。

Also there's a previous question related to the subject which probably has interesting information on the matter from different points of view.

这篇关于重新使用移位实现模?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆