计算C中的长距离

计算C中的长距离,c,C,我正在用C写一个程序来计算不同数据类型的范围。请查看以下代码: #include <stdio.h> main() { int a; long b; for (a = 0; a <= 0; --a) ; ++a; printf("INT_MIN: %d\n", a); for (a = 0; a >= 0; ++a) ; --a; printf("INT_MAX: %d\n

我正在用C写一个程序来计算不同数据类型的范围。请查看以下代码:

#include <stdio.h>

main()
{
    int a;
    long b;

    for (a = 0; a <= 0; --a)
        ;
    ++a;
    printf("INT_MIN: %d\n", a);
    for (a = 0; a >= 0; ++a)
        ;
    --a;
    printf("INT_MAX: %d\n", a);
    for (b = 0; b <= 0; --b)
        ;
    ++b;
    printf("LONG_MIN: %d\n", b);
    for (b = 0; b >= 0; ++b)
        ;
    --b;
    printf("LONG_MAX: %d\n", b);
}
程序花了很长时间暂停打印长值。我还将printf放在第三个循环中,以测试这里没有提到的程序。我发现b即使变成正值也没有退出循环

我用了同样的计算方法。为什么它对int有效,但不会很长时间?

In

printf("LONG_MIN: %d\n", b);
格式说明符是%d,它适用于integersint。它应该更改为%ld以打印长整数long,在

printf("LONG_MAX: %d\n", b);
这些声明应该是

printf("LONG_MIN: %ld\n", b);
&

这种方法可能不适用于所有编译器,例如gcc,更简单的方法是使用它


同时检查。

您使用了错误的格式说明符。由于b是long类型,请使用

事实上,如果启用了所有警告,编译器可能会警告您,例如:

t.c:19:30: warning: format specifies type 'int' but the argument has type 'long' [-Wformat]
    printf("LONG_MIN: %d\n", b);
在C语言中,有符号整数的减量超过其最小值,类似于递增超过最大值。你的程序可以做任何事情

例如

正确的做法是:

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

int main()
{
    printf("INT_MIN = %d\n", INT_MIN);
    // etc.
}

如前所述,您提供的代码调用未定义的行为。因此它可以计算出你想要什么或者发射核导弹

未定义行为的原因是为了测试数据类型的范围而引发的有符号整数溢出

如果你只想知道int、long和friends的范围,那么这里就是你要寻找的地方。但是如果你真的想

[…]以计算范围[…]

。。。无论出于什么原因,您都可以使用相应类型的无符号变量执行此操作,尽管请参见末尾的注释,并按如下方式计算最大值:

unsigned long calculate_max_ulong(void) {
  unsigned long follow = 0;
  unsigned long lead = 1;
  while (lead != 0) {
    ++lead;
    ++follow;
  }
  return follow;
}
这只会导致从最大值到0的无符号整数换行,这不属于未定义行为。根据上面的结果,您可以得到相应签名类型的最小值和最大值,如下所示:

assert(sizeof(long) == sizeof(unsigned long));
unsigned long umax_h = calculate_max_ulong() / 2u;
long max = umax_h;
long min = - max - 1;


假设有符号类型的补码为2,且无符号类型仅比有符号类型多一个值位。有关详细信息,请参见§6.2.6.2/2 N1570。

尝试使用%ldfor long,但这是UB。使用ld而不是d来打印long int。如果使用gcc,请始终使用-Wall选项编译。编译器将向您提供有关printf格式的警告。我正在用C编写一个程序来计算不同数据类型的范围,而不是,比如说,包括limits.h,并且简单地使用LONG_MIN和LONG_MAX?有符号类型溢出调用未定义的行为!为什么您希望在运行时计算它,而不仅仅是使用限制中的内容。h超出了我的范围。抱歉,第二个示例是实现定义的。这不是获取最大最小值的正确方法。它实际上会在某些体系结构上导致未定义的行为。@2501您能给我指出标准中使其实现定义的条款吗?你说的不正确是什么意思?如前所述,正确的方法是使用limits.h。即使假设2的补码,无符号类型的范围也可能不是相应有符号类型的两倍。@2501实际上,无符号范围可能更大。我不知道这是可能的,所以今天我学到了一些东西。因为我仍然认为我的答案提供了有用的内容,所以我将保留它,但我对它的限制做了进一步的说明。@2501我同意限制.h是一条路要走。经过编辑,我的答案现在应该提供有用的信息,这也要感谢这次讨论。
#include <limits.h>
#include <stdio.h>

int main()
{
    printf("INT_MIN = %d\n", INT_MIN);
    // etc.
}
unsigned long calculate_max_ulong(void) {
  unsigned long follow = 0;
  unsigned long lead = 1;
  while (lead != 0) {
    ++lead;
    ++follow;
  }
  return follow;
}
assert(sizeof(long) == sizeof(unsigned long));
unsigned long umax_h = calculate_max_ulong() / 2u;
long max = umax_h;
long min = - max - 1;