gpt4 book ai didi

c - 返回未知 int 类型的范围

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

我被分配了一个问题,其中有人可能会输入任何类型的有符号/无符号整数,并且两个函数必须使用按位运算等返回各自的最小值和最大值。

我正在尝试调整我对二进制补码的了解——范围由 -(2n-1) 到 (2n-1 - 1) 定义对于有符号值,0 到 (2n - 1) 对于无符号值。

但是,当我对无符号使用以下方法时:

void create_minmax_unsigned() {
unknownun exponent = (sizeof(unknownun) * 8) - 1;
unknownun max = (1 << exponent) - 1;
printf("The max is %d", max);
}

对于签名:

void create_minmax_signed() {
unknowns exponent = (sizeof(unknowns) * 8) - 1;
unknowns min = ((1 << exponent) + 1) - 1;
unknowns max = (1 << exponent) - 1;
}

这种方法适用于 char (un/s)、short (un/s)、int (un/s)、long (un/s),但不适用于 64 位的 long long。

编辑:它实际上为所有 int 类型返回正确的位数。但是,对于 long long,它没有显示正确的范围。

最佳答案

long long 的原因计算失败的原因是分配的 RHS 计算为 int并且您正尝试移动对于 int 来说太大的值.

这个游戏逐步得出答案——只有最终代码才是真正可行的。早期版本有各种问题需要解决,一次解决一个问题。

您需要将 RHS 强制转换为指定类型:

void create_minmax_unsigned() {
unknownun exponent = (sizeof(unknownun) * 8) - 1;
unknownun max = ((unknownun)1 << exponent) - 1;
printf("The max is %d", max);
}

void create_minmax_signed() {
unknowns exponent = (sizeof(unknowns) * 8) - 1;
unknowns min = (((unknowns)1 << exponent) + 1) - 1;
unknowns max = ((unknowns)1 << exponent) - 1;
}

您在返回多个值时遇到问题。使用 <inttypes.h> 可以使您的打印代码更加健壮和 intmax_tuintmax_t类型转换:

void create_minmax_unsigned() {
unknownun exponent = (sizeof(unknownun) * 8) - 1;
unknownun max = ((unknownun)1 << exponent) - 1;
printf("The max is %" PRIuMAX, (uintmax_t)max);
}

void create_minmax_signed() {
unknowns exponent = (sizeof(unknowns) * 8) - 1;
unknowns min = (((unknowns)1 << exponent) + 1) - 1;
unknowns max = ((unknowns)1 << exponent) - 1;
printf("The max is %" PRIdMAX, (intmax_t)max);
printf("The min is %" PRIdMAX, (intmax_t)min);
}

解决溢出问题

到目前为止,这使您的计算基本上没有变化;它只是确保值的类型正确。但是,您的计算容易受到数字溢出的影响,这(可能)非常糟糕——它会导致带符号整数类型的未定义行为和无符号类型的错误答案。

对于无法使用更大的类型来掩盖错误的无符号类型,您需要小心创建 2n-1,因为 2<sup>n</sup>大于可以存储的值,所以它看起来像 0。当你减去 1 时,你会得到正确的答案,但你真的不需要移位/求幂。

void create_minmax_unsigned() {
unknownun max = (unknownun)0 - 1;
printf("The max is %" PRIuMAX, (uintmax_t)max);
}

对于有符号类型,您不能使用 2n-1 - 1,因为 2n-1 无法表示。不过,您可以使用 2 * (2n-2 - 1) + 1。负数限制是减去一个值而取反,导致:


未经测试的代码(错误):

void create_minmax_signed() {
unknowns exponent = (sizeof(unknowns) * 8) - 2;
unknowns max = 2 * ((unknowns)1 << exponent) + 1;
unknowns min = -max - 1;
printf("The max is %" PRIdMAX, (intmax_t)max);
printf("The min is %" PRIdMAX, (intmax_t)min);
}

经过测试的代码(不是那么有问题):

#include <inttypes.h>
#include <stdio.h>

typedef signed long long unknowns;
void create_minmax_signed(void);

void create_minmax_signed(void)
{
unknowns exponent = (sizeof(unknowns) * 8) - 2;
unknowns max = 2 * (((unknowns)1 << exponent) - 1) + 1;
unknowns min = -max - 1;
printf("The max is %+" PRIdMAX "\n", (intmax_t)max);
printf("The min is %+" PRIdMAX "\n", (intmax_t)min);
}

int main(void)
{
create_minmax_signed();
return 0;
}

编译:

/usr/bin/gcc -g -O3 -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Wold-style-declaration -Werror  mnx.c -o mnx

样本运行:

$ ./mnx
The max is +9223372036854775807
The min is -9223372036854775808
$

关于c - 返回未知 int 类型的范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24889623/

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