Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 返回未知int类型的范围_C - Fatal编程技术网

C 返回未知int类型的范围

C 返回未知int类型的范围,c,C,我被分配了一个问题,有人可以输入任何类型的有符号/无符号整数,两个函数必须使用位运算返回各自的最小值和最大值,等等 我试图调整我所知道的关于二的补码的知识-范围是由-(2n-1)到(2n-1-1)定义的,对于有符号的值,范围是由0到(2n-1)定义的,对于无符号的值 但是,当我对unsigned使用以下方法时: void create_minmax_unsigned() { unknownun exponent = (sizeof(unknownun) * 8) - 1; unk

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

我试图调整我所知道的关于二的补码的知识-范围是由-(2n-1)到(2n-1-1)定义的,对于有符号的值,范围是由0到(2n-1)定义的,对于无符号的值

但是,当我对unsigned使用以下方法时:

void create_minmax_unsigned() {
    unknownun exponent = (sizeof(unknownun) * 8) - 1;
    unknownun max = (1 << exponent) - 1;
    printf("The max is %d", max);
}
void create\u minmax\u unsigned(){
未知指数=(sizeof(unknownun)*8)-1;

unknownun max=(1您不能只移动
1计算失败的原因是
long-long
赋值的RHS被计算为
int
,您试图移动的值对于
int
来说太大

这个spiel逐步开发了答案-只有最终的代码才是真正可行的。早期版本有各种各样的问题需要解决,一次解决一个问题

您需要强制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;
}
解决溢出问题 到目前为止,这使您的计算基本保持不变;它只是确保值的类型正确。但是,您的计算容易受到数字溢出的影响,这(可能)非常糟糕-它会导致有符号整数类型的未定义行为和无符号类型的错误答案

对于无法使用较大的类型来掩盖罪恶的无符号类型,您需要小心地创建2n-1,因为
2n
大于可以存储的大小,因此它看起来像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。负限制是用一减去一的值求反,从而导致:


未测试代码(错误):

样本运行:

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

您使用的是哪种编译器和平台?(1)如果
sizeof(long-long)==4
,则
CHAR\u BITS==16
或更大的值(如果编译器符合标准)。
long
类型在符合标准的编译器中必须至少为64位。(2)你到底想做什么还不清楚。一个C函数实际上只能接受一种类型作为它的参数,除非你使用指向不同类型的指针(或者,使用
void*
指向不同类型)的变量函数。但你需要知道传递的是什么类型。我仍然猜不出任何人会如何利用它。@JonathanLeffler它可能是一个宏……好吧;宏不是函数。你想要宏还是函数?这个构造的用例是什么?你想要实现什么。这感觉像是一个;你要求的是e解决方案到X,但您确实在寻求解决Y.函数,它并不是真正有用的。它只是一个练习。您不能在函数中这样做,因为函数将其参数作为已知类型传递:
[return\u type]函数([argument\u type argument])
。您已经知道参数是什么类型的。很抱歉,这是一个非常新的问题,并且没有跟上。您是在问程序的最后一行在做什么,还是通过表达式(x+1)-1提出了一些建议?max-1不是最小值,不是最大值吗?您似乎忘记了
create\u minmax\u signed()中的
-1
max=2*((1@EOF:问题假设2是补码;答案也是。是的,你是对的;我在表达式中忘记了-1。答案用测试代码(和测试代码)更新。有一个原因我更喜欢测试后的代码…@MattMcNabb:我在顶部放了一个明确的“逐步开发”和“待解决的问题”免责声明,试图防止您的混淆再次发生。一个非常清楚的答案!另一个(非常优雅的)实现是(请参阅“最大\u未签名\u值\u类型(x)”及其签名的兄弟姐妹)
void create_minmax_unsigned() {
    unknownun max = (unknownun)0 - 1;
    printf("The max is %" PRIuMAX, (uintmax_t)max);
}
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
$