1

我在写一个定点类,但遇到了一点障碍...乘法,除法部分,我不知道如何模拟。我对师的操作员进行了非常粗鲁的刺探,但我相信这是错误的。这是它到目前为止的样子:C++:仿真定点除法/乘法

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位,因为我认为它需要在可能的溢出之前在它们被固定之前)的空间,并且相同的值为整数部分。当“部分”在其中一个操作中超过0xFFFF时,最高的16位被添加到“值”,然后该部分被屏蔽,因此只剩下最低的16位。这是在init列表中完成的。我不想问这个问题,但如果有人知道我在哪里可以找到类似这样的文档,甚至只是'诀窍'或如何做这两个操作员,我会很高兴的!我是一个昏昏沉沉的数学,我知道有人不得不这样做/之前问这个,但搜索谷歌有一次没有带我去承诺的土地...

+0

这功课吗?你基本上试图模仿浮点数学,但没有使用浮点数字符号?你看过IEEE如何处理这个问题吗? – 2011-02-17 12:43:49

+0

@Zac可悲的是,从来没有去过编程学校或什么都没有,因为你可以告诉!这是一个非常糟糕的尝试,以避免在我正在做的2D物理引擎中进行浮点运算。但我现在正在搜索IEEE,所以我会看到! – 2011-02-17 12:48:46

+0

@Zac:OP正在谈论'固定'点多重分割,而不是'浮动'点,这是有区别的。 http://en.wikipedia.org/wiki/Fixed-point_arithmetic – 2011-02-17 12:50:14

回答

2

正如Jan所说,使用一个整数。由于它看起来像是指定了16位整数和小数部分,所以可以用一个普通的32位整数来完成。

“诀窍”是要了解当您对其进行操作时,数字的“格式”会发生什么。你的格式将被描述为16.16。当您添加或减少时,格式保持不变。当你乘,你得到32.32 - 所以你需要一个64位的临时值的结果。然后你做一个>> 16位移到48.16格式,然后在16.16位取最低的32位来得到你的答案。

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

0

我建议使用一个整数值而不是单独的整体和小数部分。比加法和减法是直接在integeral同行,你可以简单地使用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
0

要启动并运行,首先需要执行(一元)inverse(x) = 1/x,然后执行a/b作为a*inverse(b)。您可能想要将中间体表示为32.32格式。