【问题标题】:Integer arithmetic overflow prevention in CC中的整数算术溢出预防
【发布时间】:2021-07-21 10:11:43
【问题描述】:

我认为以下代码可能会导致溢出,因为a * 65535 大于unsigned short int 可以容纳的值,但结果似乎是正确的。

C 中是否有一些内置机制可以将中间算术结果存储为更大的数据类型?还是只是意外?

unsigned char a = 30;
unsigned short int b = a * 65535 /100;
printf("%hu", b);

【问题讨论】:

  • 你的编译器上short int 的位宽是多少?编译器通常使用其本机位宽进行常量表达式评估,因此它最有可能在 32 位或 64 位上计算,然后将结果截断为目标位宽......这同样适用于浮点/双精度,除非您明确键入 cat (1ull, . ..1.0, 1.0f,...)

标签: c math type-conversion integer-overflow integer-promotion


【解决方案1】:

之所以有效,是因为所有比int 更窄的类型都将归入default promotion。由于unsigned charunsigned short 在您的平台上都小于int,因此它们将被提升为int,并且如果int 包含CHAR_BIT + 17 位或更多位(即a * 65535 加号的结果) 22 位或更多(这是30 * 65535 加号中的位数)。但是,如果int 的位数较少,则会发生溢出并发生未定义的行为。如果sizeof(unsigned short) == sizeof(int) 也行不通

默认提升允许更快地完成操作(因为大多数 CPU 最适合使用其本机大小的值)并且还可以防止发生一些幼稚的溢出。见

【讨论】:

    猜你喜欢
    • 2022-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-12
    • 1970-01-01
    • 2022-06-22
    相关资源
    最近更新 更多