Better ways to implement a modulo operation (algorithm question)

后端 未结 5 1466
孤城傲影
孤城傲影 2020-12-28 18:36

I\'ve been trying to implement a modular exponentiator recently. I\'m writing the code in VHDL, but I\'m looking for advice of a more algorithmic nature. The main componen

5条回答
  •  抹茶落季
    2020-12-28 19:28

    I'm not sure what you're calculating there to be honest. You talk about modulo operation, but usually a modulo operation is between two numbers a and b, and its result is the remainder of dividing a by b. Where is the a and b in your pseudocode...?

    Anyway, maybe this'll help: a mod b = a - floor(a / b) * b.

    I don't know if this is faster or not, it depends on whether or not you can do division and multiplication faster than a lot of subtractions.

    Another way to speed up the subtraction approach is to use binary search. If you want a mod b, you need to subtract b from a until a is smaller than b. So basically you need to find k such that:

    a - k*b < b, k is min

    One way to find this k is a linear search:

    k = 0;
    while ( a - k*b >= b )
        ++k;
    
    return a - k*b;
    

    But you can also binary search it (only ran a few tests but it worked on all of them):

    k = 0;
    left = 0, right = a
    while ( left < right )
    {
        m = (left + right) / 2;
        if ( a - m*b >= b )
           left = m + 1;
        else
           right = m;
    }
    
    return a - left*b;
    

    I'm guessing the binary search solution will be the fastest when dealing with big numbers.

    If you want to calculate a mod b and only a is a big number (you can store b on a primitive data type), you can do it even faster:

    for each digit p of a do
        mod = (mod * 10 + p) % b
    return mod
    

    This works because we can write a as a_n*10^n + a_(n-1)*10^(n-1) + ... + a_1*10^0 = (((a_n * 10 + a_(n-1)) * 10 + a_(n-2)) * 10 + ...

    I think the binary search is what you're looking for though.

提交回复
热议问题