我正在开发一个需要使用定点数学的项目,我无法弄清楚为什么这些数字是“滚动”,当我改变了移位量时,我能够获得足够大的数字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位宽吗?
答案 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_t
是signed int
的别名,这是int
的别名,这一事实可以通过查看online documentation或内容来证实。文件
Arduino Uno 来源中的Arduino的版本 /hardware/tools/avr/lib/avr/include/stdint.h
:
/** \ingroup avr_stdint
16-bit signed type. */
typedef signed int int16_t;