在C中查找short int变量的最大值

时间:2017-08-25 13:14:56

标签: c size short typecase

我正在研究K& R的练习2-1,目标是计算不同变量类型的范围,下面是我计算short int可以包含的最大值的函数:

short int max_short(void) {
    short int i = 1, j = 0, k = 0;
    while (i > k) {
        k = i;
        if (((short int)2 * i) > (short int)0)
            i *= 2;
        else {
            j = i;
            while (i + j <= (short int)0)
                j /= 2;
            i += j;
        }
    }
    return i;
}

我的问题是这个函数返回的值是:-32768这显然是错误的,因为我期待一个正值。我无法弄清楚问题出在哪里,我使用相同的函数(在变量类型中有变化)来计算int可以包含的最大值并且它有效...

我虽然问题可能是由于ifwhile语句中的比较造成的,因此类型转换却没有帮助......

任何想法导致了什么?提前谢谢!

编辑:感谢Antti Haapala的解释,符号位的溢出会导致未定义的行为,而不是负值。

3 个答案:

答案 0 :(得分:5)

您无法使用此类计算来推断 signed signed 的范围,因为有符号整数溢出具有未定义的行为,并且在实现中最大限度地缩小转换结果 - 定义的值,或者引发的信号。正确的解决方案是使用SHRT_MAX的{​​{1}},INT_MAX ...。通过算术推导有符号整数的最大值是标准化C语言中的一个棘手问题,自1989年第一个标准出版以来就一直如此。

请注意,K&amp; R的原始版本比C的标准化早了 11 年,甚至第二一个 - “ANSI-C”版本早于最终标准并且与它有所不同 - 它们是为一种语言而写的,这种语言几乎不是完全不同于今天的C语言。

您可以轻松地对无符号整数执行此操作:

<limits.h>

答案 1 :(得分:0)

根据定义,您无法使用相同类型的变量计算C中类型的最大值。它根本没有任何意义。当它“越过顶部”时,该类型将溢出。在有符号整数溢出的情况下,行为是未定义的,这意味着如果你尝试它会遇到一个主要的错误。

执行此操作的正确方法是从limits.h中检查SHRT_MAX

另一种更有问题的方法是创建unsigned short的最大值然后将其除以2.我们可以通过对值0进行按位求逆来创建最大值。

#include <stdio.h>
#include <limits.h>

int main()
{ 
  printf("%hd\n", SHRT_MAX); // best way

  unsigned short ushort_max = ~0u;
  short short_max = ushort_max / 2;
  printf("%hd\n", short_max);

  return 0;
}

关于您的代码的一个注释:

((short int)2*i)>(short int)0等演员阵容完全是多余的。 C中的大多数二元运算符(例如*>)实现了一种称为“通常的算术转换”的东西,这是一种隐式转换和平衡表达式类型的方法。这些隐式转换规则将静默地使两个操作数类型int尽管你的演员阵容。

答案 2 :(得分:-2)

你忘了在比较期间转换为短整数

好的,在这里我假设计算机会通过改变为负整数来处理整数溢出行为,因为我相信你已经在编写这个程序。

输出32767的代码:

car

添加了2个演员