Types 在Atmel Studio中计算3个矢量的幅值时输出不正确

Types 在Atmel Studio中计算3个矢量的幅值时输出不正确,types,floating-point,buffer-overflow,atmel,avr-studio6,Types,Floating Point,Buffer Overflow,Atmel,Avr Studio6,我在获取浮点输出时遇到了一些问题。我要做的是在三个轴上获取加速度计的输出。每个轴的输出都有一个高字节和低字节,它们组合成一个变量。然后计算这三个变量的大小:mag=sqrt(x*x+y*y+z*z)。每个轴的输出作为16位有符号整数输出 至少,它应该是这样工作的,但我甚至无法在我的程序中将两个大数字相乘以产生正确的值,我认为没有理由这样做,因为变量都应该足够大,可以容纳任何结果。代码如下: double xAccel = 0; // 16 bit X accel

我在获取浮点输出时遇到了一些问题。我要做的是在三个轴上获取加速度计的输出。每个轴的输出都有一个高字节和低字节,它们组合成一个变量。然后计算这三个变量的大小: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不起作用。结果应该是100000000。但我得到的结果是:

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

假设我将加速度总和设置为1000*1000。那只是一百万。对于int32来说足够小了。但我的输出是:

Accel Mag: 16960.00
即使是200*200,输出也是-25536.00


这一定是个愚蠢的简单问题。如果有人能帮我,我会非常感激的

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

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

如果被除法或相乘的表达式不是常量,则可以通过强制转换将它们转换为更宽的类型:
float f=(float)int_var1/(float)int_var2或者,在您的例子中,
无符号长foo=(无符号长)int_var1*(无符号长)int_var2。您还可以转换为
double
,以便计算的乘法是
double
乘法:
accelSum=(double)int\u var1*(double)int\u var2

由于“促销规则”,实际上只有一个强制转换是必要的,但两个都写同样清楚


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


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

因此,如果我在数字后添加UL,一切都会正常!我猜当你键入一个数字时,它会自动被类型转换为一个无法包含中间计算的类型,从而导致溢出。是这样吗?但是我该如何处理计算中使用的变量呢?谢谢你的帮助!你第一段的规则对我来说是新的,但有道理。也许不是最直观的业务,打字。这里肯定有一些变化。