首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用avr-gcc对浮动的隐式转换: uint8_t与uint16_t

使用avr-gcc对浮动的隐式转换: uint8_t与uint16_t
EN

Stack Overflow用户
提问于 2018-06-13 16:43:34
回答 1查看 1.3K关注 0票数 3

关于使用Arduino IDE 1.8.2 (gcc 4.9.2.)隐式转换uint8_tuint16_t,我有一个问题。硬件是一个标准的Arduino (ATMega328p)。

我使用uint8_t编写了一段代码,然后决定切换到uint16_t。(应该预见到.)

但是,对于隐式转换,它们的行为似乎略有不同,这导致了程序中的错误。

下面是一个最低限度的工作示例:

代码语言:javascript
运行
复制
void setup()
{
  uint8_t x = 15;
  uint8_t y = 5;
  float myF = y-x;

  Serial.begin(74880);
  Serial.println(myF);
}

这将在我的串行控制台上打印-10点。

这很好,也是我所期望的。

但是,如果我将x (或xy)更改为uint16_t,结果将是65526.00!如果我将myF从浮点改为int,我将再次得到-10。(我从不改变任何一个值)

当我将结果存储在有符号的数据类型中时,我假设编译器意识到了负值的可能性,并“正确地处理情况”(保留符号,就像在int情况下那样),或者打印警告,以防它对数据类型不匹配感到高兴。但是,即使将警告级别设置为"all“,它也没有显示警告。因此,我假设编译器知道如何在不丢失符号/数据的情况下处理这种情况。

而且,由于它与int作为目标数据类型一起工作,所以它不适用于更大的浮点,这让我感到惊讶。

我已经测试了我的x86系统的情况- gcc 4.7.3保留了标志。然而,在AVR的8位微控制器世界中,可能适用不同的规则/条件。(?)

那到底是怎么回事?也许有更多编译知识的人能帮上忙。

(我知道我本可以通过明确的方式避免这种情况,但因此我必须意识到这个陷阱。

所以我想知道到底是什么原因造成的,因为从uint8_t切换到uint16_t真的是一个惊喜。)

我读过,根据整数转换规则,“当对整数执行操作时,小于int的整数类型被提升为int”。我想avr-gcc会跟随整型升迁。(?)因此,我理解实际的计算通常在int上运行,然后转换为目标数据类型(在本例中为float)。这里的问题是uint16_t是相等的,但不是小于16位int的AVR,因此uint16_t不能推广吗?如果是这样的话,为什么它使用一个int作为目标类型?

为什么它使用int作为目标变量,而不使用4字节浮点数呢?为什么不警告呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-06-13 18:53:03

那到底是怎么回事?

整数晋升

如果int可以表示原始类型的所有值.,则将该值转换为int;否则,该值将转换为unsigned int。这就是所谓的整数晋升。 C11§6.3.1.1 2

使用下面的代码,y-x将每个x,y提升到int,并计算5-15,即int -10,并将值分配给mF

代码语言:javascript
运行
复制
  uint8_t x = 15;
  uint8_t y = 5;
  float myF = y-x;

使用下面的代码,y-x将每个x,y提升到unsigned,计算5u-15u,即unsigned 65526u,并将值分配给mF

代码语言:javascript
运行
复制
  uint16_t x = 15;
  uint16_t y = 5;
  float myF = y-x;

为什么是unsigned而不是intuint16_t在提升uint16_t时不满足16位int平台上的“如果int可以表示所有原始类型的值”的条件。

没有神秘,只有一个16位int/unsigned平台上的整数促销。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50842339

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档