1

我在尝试获得浮点输出时遇到了一些麻烦。我想要做的是在 3 个轴上获取加速度计的输出。每个轴的输出都有一个高字节和低字节,它们组合成一个变量。然后计算这三个变量的大小:mag = sqrt(x*x + y*y + z*z)。每个轴的输出以 16 位有符号整数形式输出。

至少,它应该是这样工作的,但我什至无法将两个大数相乘以在我的程序中产生正确的值,而且我认为没有理由这样做,因为变量都应该足够大以容纳任何结果. 这是代码:

    double xAccel = 0;              // 16 bit X acceleration value
    double accelSum = 0;
    xAccel = xAccelRead();

    accelSum = 10000*10000;
    char aMag[64];
    sprintf(aMag, "Accel Mag: %.2f", accelSum);

    clearDisplay();
    writeText(aMag,0,0,WHITE,BLACK,1);
    OLED_buffer();

xAccelRead() 的输出是一个 16 位整数。通常,“accelSum”将设置为等于上面给出的幅度方程,但现在静态数字甚至不起作用。如果我将等式设置为 100^2,它会起作用。但是 10000 * 10000 不起作用。结果应该是100,000,000。但我得到的输出是:

Accel Mag: -7936.00

我不明白为什么会这样。我尝试将类型设置为 int32、int64,现在又设置为浮点数。他们所有人都有同样的问题。我在 Atmel Studio 中设置了正确的链接器选项以允许浮点 sprintf 支持,所以这不是问题。我猜某处有溢出,但我不知道在哪里。所涉及的所有变量的类型都大到足以容纳数千亿的最大值,这远远超出了我的需要。

假设我设置了 accelSum = 1000 * 1000。那只是一百万。对于 int32 来说非常小。但我的输出是:

Accel Mag: 16960.00

即使是 200 * 200,输出也是 -25536.00。

这一定是一些愚蠢的简单问题。如果有人可以帮助我,我将不胜感激!

4

1 回答 1

3

您已经在评论中回答了大部分问题。

您的问题类似于一些程序员float f = 5 / 3;对除法计算为整数除法的惊讶,尽管它注定要分配给 a float。他们的解决方案是float f = 5.0 / 3.0;改用。

如果被除或在您的情况下相乘的表达式不是常量,您可以使用强制转换将它们转换为更广泛的类型或者float f = (float)int_var1 / (float)int_var2;,在您的情况下,unsigned long foo = (unsigned long)int_var1 * (unsigned long)int_var2;. 您还可以转换为,double以便计算出的乘法是double乘法:accelSum = (double)int_var1 * (double)int_var2;

由于“晋升规则”,实际上只需要其中一个演员表,但两者都写同样清楚。


如果您对细节感兴趣,C 标准要求选择整数常量的类型作为第一个可以表示列表中的常量的类型。在 C99(*) 中,列表是int, long, long long。在您的情况下,16 位int足以包含10000or 200,因此int被选为这些常量的类型。

(*) 想法相同,但 C90 中的列表不同。

于 2013-09-06T12:19:39.260 回答