【问题标题】:uint8_t operations, when do they overflow?uint8_t 操作,它们何时溢出?
【发布时间】:2015-10-29 13:12:42
【问题描述】:

我不确定在使用无符号字符时何时必须担心溢出。这个案例很清楚:

uint8_t a = 3;
uint8_t b = 6;
uint8_t c = a - b; // c is 253 

但是,这里发生了什么:

float d = a - b; // d is -3

在做减法之前是否都将 a 和都转换为浮点数?

或者在这种情况下:

float e = (a - b) + (a - c);

三个变量都转换成浮点数了吗?

是否有可能发生溢出的情况,即使分配给的变量是浮点数?如果 e 是浮点数、整数或其他任何值,规则是否相同?

另外,在这样的情况下会发生什么:

int a = std::abs(a - b);

【问题讨论】:

  • 无符号操作永远不会溢出,它们只是环绕。 uint8_t c = a - b; 表示 uint8_t c = (uint8_t)((int)a - (int)b); 在转换后产生包装结果
  • 添加到@LưuVĩnhPhúc 的评论中,溢出很糟糕,非常糟糕。这是未定义的行为。无符号整数永远不会溢出。他们改为使用模 2^n 算术。

标签: c++ char overflow unsigned-char integer-promotion


【解决方案1】:

您的情况不是字符到浮点数转换的结果,而是由于整数提升规则。 Cppreference 声明如下(强调我的):

小整数类型(如 char)的纯右值可以转换为较大整数类型(如 int)的纯右值。特别是,算术运算符不接受小于 int 的类型作为参数,并且在左值到右值转换后自动应用整数提升(如果适用)。此转换始终保留该值。

还有:

如果 unsigned char 或 unsigned short 可以保存其整个值范围,则可以将其转换为 int,否则可以将其转换为 unsigned int。

因此,在您的情况下,- 运算符将值转换为整数,然后将其转换为浮点数。只有对c 的赋值转换回uint8_t(溢出)。

这同样适用于std::abs 示例:在减法之前转换值,并将结果传递给函数。

有关算术运算的有符号/无符号提升的更多详细信息,请参阅以下答案:https://stackoverflow.com/a/6770275/3198247

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-14
    • 2011-11-19
    • 2020-01-11
    • 2012-03-05
    • 2013-07-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多