C ++:仿真定点除法/乘法

时间:2011-02-17 12:35:55

标签: c++ bit-manipulation multiplication fixed-point integer-division

我正在编写一个固定点类,但遇到了一些障碍......乘法,除法部分,我不知道如何模拟。我对分区操作员进行了非常粗略的尝试,但我确信这是错误的。以下是目前的情况:

class Fixed
{
    Fixed(short int _value, short int _part) : 
        value(long(_value + (_part >> 8))), part(long(_part & 0x0000FFFF)) {};

    ...

    inline Fixed operator -() const  // example of some of the bitwise it's doing
    {
        return Fixed(-value - 1, (~part)&0x0000FFFF);
    };

    ...

    inline Fixed operator / (const Fixed & arg) const // example of how I'm probably doing it wrong
    {
        long int tempInt = value<<8 | part;
        long int tempPart = tempInt;
        tempInt  /= arg.value<<8 | arg.part;
        tempPart %= arg.value<<8 | arg.part;
        return Fixed(tempInt, tempPart);
    };

    long int value, part; // members
};

我...我不是一个非常优秀的程序员,哈哈!

类的'部分'是16位宽(但是表示为长32位,因为我认为它需要在它们被修复之前可能存在溢出的空间)并且同样适用于'值'这是整数部分。当'part'在其中一个操作中超过0xFFFF时,最高的16位被加到'value',然后该部分被屏蔽,因此只保留最低的16位。这是在初始列表中完成的。

我讨厌问,但如果有人知道我在哪里可以找到类似这样的文档,或者甚至只是“技巧”或如何做这两个操作符,我会很高兴的!在谈到数学方面,我是一个狡猾的人,我知道有人不得不在此之前做过/问过这个问题,但是搜索谷歌曾经没有把我带到承诺的土地......

3 个答案:

答案 0 :(得分:2)

正如Jan所说,使用一个整数。因为看起来你正在指定16位整数和小数部分,所以你可以用普通的32位整数来做这个。

“技巧”是为了实现对数字进行操作时数字“格式”的变化。您的格式将被描述为16.16。添加或减去时,格式保持不变。当你乘以时,得到32.32 - 所以你需要一个64位的临时值来得到结果。然后你做一个&gt;&gt; 16班次以达到48.16格式,然后拿下底部的32位来得到你在16.16的答案。

我对这个部门有点生疏 - 在DSP中,我学到了这些东西,我们尽可能避免(昂贵的)划分!

答案 1 :(得分:0)

我建议使用一个整数值而不是单独的整数和小数部分。比加法和减法直接是整数对应物,你可以简单地使用64位支持,这些日子都是常见的编译器:

  • 乘:

    operator*(const Fixed &other) const {
        return Fixed((int64_t)value * (int64_t)other.value);
    }
    
  • 司:

    operator/(const Fixed &other) const {
        return Fixed(((int64_t)value << 16) / (int64_t)other.value);
    }
    

64位整数

  • 在gcc上,stdint.h(或cstdint,将它们置于std::名称空间中)应该可用,因此您可以使用我上面提到的类型。否则,它在32位目标上为long long,在64位目标上为long
  • 在Windows上,它始终为long long__int64

答案 2 :(得分:0)

要开始运行,首先要实现(一元)inverse(x) = 1/x,然后将a/b实现为a*inverse(b)。您可能希望将中间体表示为32.32格式。