【学习笔记】Algorithmes with numbers(1)

使用递归思想解决乘法、除法、指数运算、求最大公约数等的C语言代码实现:

乘法:

公式:x*y = 2*x*(y/2 向下取整) (y为偶数) 或者 2*x*(y/2 向下取整)+x (y为奇数)

ulong multiply(ulong x,ulong y)
{
    if (y == 0) return 0;

    ulong z, half = y >> 1;
    z = multiply(x,half);

    if (y%2) return x+(z << 1);
    else return z << 1;
}

除法,其实就是求一个商和一个余数:

void divide(ulong x,ulong y, struct divide_result *result)
{
    if (x == 0)
    {
        result->q = 0;
        result->r = 0;
        return;
    }

    ulong half = x >> 1;

    struct divide_result z;

    divide(half, y, &z);

    result->q = z.q << 1;
    result->r = z.r << 1;

    if (x%2)
    {
        result->r ++;
    }

    if (result->r >= y)
    {
        result->r -= y;
        result->q ++;
    }

    return;
}

指数运算,公司可以参考乘法公式的思路:


ulong modexp(ulong x, ulong y, ulong N)
{
    if (y == 0) return 1;

    ulong z;
    ulong half = y >> 1;

    z = modexp(x,half,N);

    if (y%2) return multiply(multiply(z,z),x)%N;
    else return multiply(z,z)%N;
}   

求最大公约数,这里利用了一个欧几里德发明的公式:

gcd(a,b) = gcd(a mod b, b)

ulong euclid(ulong x,ulong y)
{
    if (y == 0) return x;
    return euclid(y, x%y);
}
太简单了吧,哈哈

还有一个扩展公式:

void extended_euclid(ulong x, ulong y, struct extend_euclid *result)
{
    if (y == 0)
    {
        result->a = 1;
        result->b = 0;
        result->d = x;

        return;
    }

    struct extend_euclid z;

    extended_euclid(y, x%y, &z);

    struct divide_result r;
    divide(x, y, &r);

    result->a = z.b;
    result->b = z.a - multiply(r.r, z.b);
    result->d = z.d;
}


你可能感兴趣的:(【学习笔记】Algorithmes with numbers(1))