Arduino可变大小和固定点
我正在做一个项目,我需要使用定点数学,我不知道为什么数字会“滚动”,当我将轮班数量从16改为8,最后改为4时,我能够得到一个足够大的数字。以下是我目前使用的代码:Arduino可变大小和固定点,arduino,fixed-point,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 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));
}
当SHIFT_AMOUNT=8时,我只能存储从-128到128的变量,但由于我使用的是32位变量,16位移位不应该将小数点移到“中间”,留下两个16位部分,一个用于整数,另一个用于小数?int32\u的整个范围不应该是−2147483648到2147483647,换班时间为16?是否有一个设置我错过了,或者我只是对它的工作方式有点偏离
如果SHIFT_AMOUNT=4,我得到一个我需要的范围,但这似乎不正确,因为我在网上看到的所有其他示例都使用16位移位
编辑
如果我没有弄错的话,当使用一个16位宽的类型时,移动8位,整个类型保留8位,分形类型保留8位,范围从-128到128。因此,需要使用4位移位将整个范围增加到-32768到32767,这是否正确?如果这是正确的,那么int32\t不是真正的32位宽吗
EDIT2
帕特里克·特伦丁指出了我错在哪里。除了我从链接问题中复制的部分外,所有内容都是正确的。我投的是int而不是int32\u t。int类型是16位宽的,因此必须使用4来获得所需的范围 改变这一点:
#define FLOAT2FIXED(x) ((int)((x) * (1 << SHIFT_AMOUNT)))
为什么不使用avr gcc中的一个定点原语?@IgnacioVazquez Abrams我之所以要做这件事的原因之一是为了了解它是如何工作的,结果应该是什么,它是如何制作的,并获得更好的理解。如果我不理解它是如何工作的,为什么工作,那么我就不知道库是否给了我一个错误的值,或者我的其他代码是否有bug。我想我明白这是怎么回事,我更新了我的问题,试图让它更清楚一点。@AndyBraham在Arduino中
(int)
的大小是16位
,为什么你在宏中将值转换为int
,而不是int32\u t
?我错过了那个,我知道有一些小问题,谢谢。没有后缀的变量比其他变量小,这是一种典型的设置吗?我的意思是我会认为int=最高可能值(int32_t)。@我扩展了我的答案来回答你的问题,希望它能有所帮助。(:
#define FLOAT2FIXED(x) ((int)((x) * (1 << SHIFT_AMOUNT)))
#define FLOAT2FIXED(x) ((int32_t)((x) * (1 << SHIFT_AMOUNT)))
/** \ingroup avr_stdint
16-bit signed type. */
typedef signed int int16_t;