Arduino可变大小和固定点

时间:2016-06-12 14:48:40

标签: arduino fixed-point

我正在开发一个需要使用定点数学的项目,我无法弄清楚为什么这些数字是“滚动”,当我改变了移位量时,我能够获得足够大的数字16到8,最后是4.这是我目前使用的代码:

#define SHIFT_AMOUNT 8
#define SHIFT_MASK ((1 << SHIFT_AMOUNT) - 1)
#define FIXED_ONE (1 << SHIFT_AMOUNT)
#define INT2FIXED(x) ((x) << SHIFT_AMOUNT)
#define FLOAT2FIXED(x) ((int)((x) * (1 << SHIFT_AMOUNT)))
#define FIXED2INT(x) ((x) >> SHIFT_AMOUNT)
#define FIXED2FLOAT(x) (((float)(x)) / (1 << SHIFT_AMOUNT))

int32_t test = FLOAT2FIXED(1.00);

void setup()
{
   Serial.begin(57600);
}

void loop(){

   test += FLOAT2FIXED(1.00);
   Serial.println(FIXED2FLOAT(test));

}

输出:

1
2
3

...

127
-128
-127
-126

当SHIFT_AMOUNT = 8时,我只能存储-128到128的变量,但由于我使用的是32位变量,因此不应该将16位移位小数点移动到“中间”,留下2个16位部分,一个用于整数而另一个用于小数? int32_t的整个范围不应该是-2,147,483,648到2,147,483,647,而在16的位移?是否有一个我缺少的设置,或者我对这是如何工作的方式还不远?

如果SHIFT_AMOUNT = 4,我得到一个我需要的范围,但这似乎不对,因为我在网上看到的所有其他例子都使用16位移位。

Here is a link showing what I am looking to do

修改

如果我有正确的话,当使用16位宽的类型时移位8位,整体留下8位,分形的8位留下-128到128的范围。因此需要使用4位移位增加整个范围到-32,768到32,767这是对的吗?如果这是正确的那么int32_t不是真正的32位宽吗?

EDIT2

Patrick Trentin指出我哪里出错了。除了从链接问题中复制的部分外,一切都是正确的。我投的是 int 而不是 int32_t 。 int类型是16位宽,因此必须使用4来获得我需要的范围。

1 个答案:

答案 0 :(得分:1)

改变这个:

#define FLOAT2FIXED(x) ((int)((x) * (1 << SHIFT_AMOUNT)))

进入这个:

#define FLOAT2FIXED(x) ((int32_t)((x) * (1 << SHIFT_AMOUNT)))

基本原理:Arduino Uno上int的大小为16-bit(请参阅documentation),这会限制您所使用的值的大小存储在int32_t变量中 16位

编辑

int16_tsigned int的别名,这是int的别名,这一事实可以通过查看online documentation或内容来证实。文件

  

Arduino的版本 /hardware/tools/avr/lib/avr/include/stdint.h

Arduino Uno 来源中的

/** \ingroup avr_stdint
    16-bit signed type. */

typedef signed int int16_t;