c++ 模拟定点除法/乘法

vawmfj5a  于 12个月前  发布在  其他
关注(0)|答案(3)|浏览(119)

我正在写一个Fixedpoint类,但是遇到了一些问题.乘法,除法部分,我不知道如何模拟。我在除法运算符上做了一个非常粗略的尝试,但是我确定它是错误的。下面是它到目前为止的样子:

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
};

字符串
我不是一个很好的程序员,哈哈!
该类的part是16位宽(但表示为32位长,因为我想它需要空间来处理可能的溢出,然后才能修复),对于整数部分value也是如此。当“部分”在其中一个操作中超过0xFFFF时,最高的16位被添加到“值”,然后部分被屏蔽,所以只剩下最低的16位。这在init列表中完成。
我不想问,但如果有人知道我在哪里可以找到这样的东西的文档,甚至只是'技巧'或如何做这两个操作符,我会很高兴!我是一个傻瓜,当谈到数学,我知道有人已经做/问这个之前,但搜索谷歌有一次没有带我到乐土.

vwkv1x7d

vwkv1x7d1#

正如Jan所说,使用一个整数。因为它看起来像你指定的16位整数和小数部分,你可以用一个普通的32位整数来完成。
“诀窍”是要意识到当你对数字进行运算时,数字的“格式”会发生什么变化。你的格式将被描述为16.16。当你进行加法或减法时,格式保持不变。当你进行乘法时,你得到32.32 --所以你需要一个64位的临时值作为结果。然后你做一个>>16移位,以得到48.16格式,然后取最下面的32位,得到16.16中的答案。
我对除法有点生疏了--在DSP,我学到了这些东西,我们尽可能避免(昂贵的)除法!

dojqjjoe

dojqjjoe2#

要让它运行起来,首先实现(一元)inverse(x) = 1/x,然后将a/b实现为a*inverse(b)

icnyk63a

icnyk63a3#

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

  • 乘法:
operator*(const Fixed &other) const {
     return Fixed(((int64_t)value * (int64_t)other.value) >> 16);
 }

字符串
1表示为1 << 16,因此您需要在末尾除以1 << 16以进行补偿。

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


1表示为1 << 16,因此您需要在补偿之前乘以1 << 16。
64-位整数是

  • 在gcc上,stdint.h(或cstdint,将它们放在std::命名空间中)应该是可用的,所以你可以使用我上面提到的类型。否则,在32位目标上是long long,在64位目标上是long
  • 在Windows上,它总是long long__int64

相关问题