如何计算(a次b)除以c仅使用32位整数类型,即使b次不适合这种类型 [英] how to calculate (a times b) divided by c only using 32-bit integer types even if a times b would not fit such a type

查看:125
本文介绍了如何计算(a次b)除以c仅使用32位整数类型,即使b次不适合这种类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

将以下内容视为参考实现:

Consider the following as a reference implementation:

/* calculates (a * b) / c */
uint32_t muldiv(uint32_t a, uint32_t b, uint32_t c)
{
    uint64_t x = a;
    x = x * b;
    x = x / c;
    return x;
}

我对不需要的实现(在C或伪代码中)感兴趣一个64位整数类型。

I am interested in an implementation (in C or pseudocode) that does not require a 64-bit integer type.

我开始草拟一个如下概述的实现:

I started sketching an implementation that outlines like this:

/* calculates (a * b) / c */
uint32_t muldiv(uint32_t a, uint32_t b, uint32_t c)
{
    uint32_t d1, d2, d1d2;
    d1 = (1 << 10);
    d2 = (1 << 10);
    d1d2 = (1 << 20); /* d1 * d2 */
    return ((a / d1) * (b /d2)) / (c / d1d2);
}

但难以选择d1和d2的值来避免溢出((a / d1)*(b / d2)< = UINT32_MAX)并最小化整个计算的误差。

But the difficulty is to pick values for d1 and d2 that manage to avoid the overflow ((a / d1) * (b / d2) <= UINT32_MAX) and minimize the error of the whole calculation.

有什么想法?

推荐答案

我已经改编了由 Paul for unsigned int(通过省略正在处理的部分)迹象)。该算法基本上是古埃及乘法 a 分数 floor(b / c)+(b%c)/ c (斜杠表示实际除法)。

I have adapted the algorithm posted by Paul for unsigned ints (by omitting the parts that are dealing with signs). The algorithm is basically Ancient Egyptian multiplication of a with the fraction floor(b/c) + (b%c)/c (with the slash denoting real division here).

uint32_t muldiv(uint32_t a, uint32_t b, uint32_t c)
{
    uint32_t q = 0;              // the quotient
    uint32_t r = 0;              // the remainder
    uint32_t qn = b / c;
    uint32_t rn = b % c;
    while(a)
    {
        if (a & 1)
        {
            q += qn;
            r += rn;
            if (r >= c)
            {
                q++;
                r -= c;
            }
        }
        a  >>= 1;
        qn <<= 1;
        rn <<= 1;
        if (rn >= c)
        {
            qn++; 
            rn -= c;
        }
    }
    return q;
}

只要符合32位,该算法就会产生确切的答案。您也可以选择返回余下的 r

This algorithm will yield the exact answer as long as it fits in 32 bits. You can optionally also return the remainder r.

这篇关于如何计算(a次b)除以c仅使用32位整数类型,即使b次不适合这种类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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