gpt4 book ai didi

c - 在 C 中使用 unsigned 并产生负临时结果

转载 作者:太空宇宙 更新时间:2023-11-04 02:35:29 26 4
gpt4 key购买 nike

据我了解,在 C 中,unsigned 类型在整数环模 4294967296 中的行为类似于算术(假设 unsigned 具有 32 位长度)。

因此,从基本环理论看来,如果我们有一个涉及 * + -< 的整数(现在我指的是 ℤ!)计算,那么无论暂时发生什么样的上溢和下溢,只要最终结果在[0, 2^32]范围内,最终结果都是正确的?

例如,在下面的计算中:

#include <stdio.h>

int main(void){

unsigned v = 50000;
unsigned w = 100000;
unsigned x = 300000;
unsigned y = 20000;
unsigned z = 4000000000;

unsigned r = v*w - x*y + z;

printf("v*w - x*y + z = %u \n", r);

return 0;
}

我们得到的临时结果与用 ℤ 计算得到的结果不同,但我们仍然得到正确答案。

这是对的还是会出什么问题?

最佳答案

根据 C11 6.2.5 Types/9(我的重点):

A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type.

换句话说,如果类型是无符号的,并且您要使用的模数值是 UINT_MAX + 1,并且类型是正确的宽度(在这种特殊情况下,所有这些都是正确的),这将按预期工作。

但是,您应该正确地将常量指定为无符号,以确保常量本身没有溢出问题(在这种情况下,C 将使用更宽的有符号类型,因此,假设您可以将更宽的类型分配给unsigned int,应该没有问题 - 例如,如果您没有使用二进制补码实现,则可能会出现问题,尽管这不太可能)。

您还应该使用 保证 足够大的类型,因为 unsigned int 在某些平台上可能小于 32 位宽。

换句话说,你的陈述应该是这样的形式:

unsigned long z = 4000000000U;

当然,这意味着您可能需要进行自己的模运算,因为 unsigned long 可能超过 32 位宽.

当然,如果您的平台提供它们,更优选使用固定宽度类型,在您的情况下为 uint32_t。这样,您将获得一个 Goldilocks 类型(既不太小也不太大,绝对是二进制补码))并且您可以让 C 本身处理模运算:

uint32_t z = 4000000000U;

是我想要的解决方案。

关于c - 在 C 中使用 unsigned 并产生负临时结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38004551/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com