首页 > 解决方案 > C 是否保证 32 位整数运算?

问题描述

在 C 中,假设int是 32 位,

uint64_t x = 1000000u * 1000000u;

这通常通过将 32 位结果的数字相乘,丢弃溢出位,然后用零扩展分配给x.

语言是否保证这一点,或者编译器是否可以选择以 64 位执行所有操作,从而给出数学上准确的结果?

(我知道语言标准int首先允许使用 64 位。我说的int是 32 位的情况。)

标签: c

解决方案


uint64_t x = 1000000u * 1000000u;

您声明的假设是int32 位。为了 100% 清楚,我们需要假设UINT_MAX2 32 -1 或4294967295。(标准要求unsigned int范围至少为 0 到 65535,这意味着大小至少为 16 位——但它可以有填充位。)几乎可以肯定是同一件事(我不知道任何 C 实现有填充位),但是如果我们想问标准保证什么,我们应该明确。

给定这个假设,常数1000000u是类型unsigned int,乘法的结果3567587328u也是类型unsigned int。该值被转换为uint64_t(不丢失信息)并存储在x.

uint64_t保证完全是 64 位宽,没有填充位。没有满足这些条件的类型的实现将不会定义uint64_t,因此上述内容无法编译。(当然,我假设这指的uint64_t是标准<stdint.h><inttypes.h>标题中定义的。)

算术表达式的一般规则是表达式的类型取决于其操作数的类型,而不是其操作数的值或它出现的上下文。如果我们放弃关于 的上限的假设unsigned int,则常数1000000u可以是unsigned int或类型unsigned long,无论哪种类型大到足以容纳它——但乘积的值与常数的类型相同,即使这会导致溢出环绕。(严格来说,无符号操作不会溢出。)


推荐阅读