Arduino 可变大小和定点

Arduino Variable Size and Fixed Point

我正在做一个需要使用定点数学的项目,我无法弄清楚为什么数字是 "Rolling Over",当我改变将数量从 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 位到 "Middle" 留下 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 来获得我需要的范围。

改变这个:

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

进入这个:

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

基本原理int 的大小在 Arduino Uno 上是 16-bit(参见 documentation),这限制了您存储在 int32_t 变量中的值到 16 位 .


编辑

事实上 int16_tsigned int 的别名,signed intint 的别名,可以通过查看 online documentation 或文件内容

arduino-version/hardware/tools/avr/lib/avr/include/stdint.h

Arduino Uno 来源中:

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

typedef signed int int16_t;