【问题标题】:signed / unsigned ints有符号/无符号整数
【发布时间】:2011-05-25 01:57:34
【问题描述】:

假设我有一个 C 脚本并声明了一些 unsigned int。然后,我编写了一个 while 循环,它会自动增加这些值并将它们打印出来:在用户从命令行停止之前没有限制。一旦我达到一个非常高的数字(20 亿),计算机就会从 -20 亿开始计数。我怎样才能防止这种情况?看,我可以轻松地输入,比如说“99999999999999”而不会导致任何崩溃:为什么我不能在我的 32 位终端上执行此操作?我已经尝试过 long long int、signed 和 unsigned 但我仍然有这个问题。截图如下:http://img577.imageshack.us/img577/6558/schermata20110524a01012.png

谢谢, J.

【问题讨论】:

  • C 不是一种脚本语言。 ;)
  • 您可能正在使用未签名的存储空间,但您将其打印为已签名。如果您使用 printf,请使用 %u 而不是 %i 或 %d。

标签: c int signed


【解决方案1】:

计算机没有有符号/无符号的概念,这是对值的解释问题。相同的值可以解释为 -1 或 65535,具体取决于您定义数据类型的方式。在你的情况下 - 循环永远不会进入负数,因为对于那种数据类型 - 没有这样的事情。相反,正值范围将大于signed int 的范围。

关于屏幕截图 - 你是如何打印的?例如,如果您使用%d 进行打印 - 它会将值解释为signed。改用%u 让程序将值解释为unsigned

【讨论】:

    【解决方案2】:

    你是如何打印出来的?您使用的是printf("%u", i),还是printf("%i", i)

    %i 会认为 int 已签名,即使它不是。要打印无符号整数,请使用%u

    【讨论】:

    • %i 仅适用于 intsigned intshort。对于unsigned int,应使用%u,对于unsigned long long,应使用%llu(但请注意,某些版本的Windows 使用非标准说明符)
    • 亲切-谢谢! unsigned int 可以有多大?我想存储一个可能轻松超过 20 亿的价值!
    • unsigned int 可以保存从 0 到 UINT_MAX 的值。通常,UINT_MAX 是 2^32,即 40 亿,但这是特定于平台的。同样,unsigned long long 的范围为 0-ULLONG_MAX。这些宏位于limits.h
    • 谢谢!你们救了我,但是... D'oh!使用“unsigned long long int”会导致程序产生 3 秒的延迟。 “实测时间:6 秒 624 毫秒” “实测时间:9 秒 297 毫秒” 好吧,会改进的!谢谢!
    【解决方案3】:

    32 位数字的范围受到限制,因为它只有 32 位。您不能以 32 位存储 60- 70- 等位数。

    您可以使用 unsigned long long 之类的东西,它可能是 64 位的,因此范围更大,但仍然有限制。 (2^64,但这是一个 非常 大的数字)。如果您确实需要“无限”,请查看 bigint 库,例如 GMP。


    编辑:正如其他发帖者所指出的,确保您在格式字符串中使用正确的转换说明符到printf

    • %d, %i: int, signed int, short
    • %u: unsigned int, unsigned short
    • %llu: unsigned long long
    • %lld, %lli: long long

    请注意,某些版本的 Windows 对 long long 类型有非标准格式说明符。

    【讨论】:

    • 我尝试从 int 更改为 long long int 但结果与上面截图中的结果相同:(
    • @Joseph:请参阅有关 printf 使用哪个转换说明符的帖子,这可能是您尝试使用 long long int 失败的原因。
    【解决方案4】:

    部分是关于如何打印值。

    如果你说

    printf("%d\n", your_unsigned_int);
    

    那么即使 int 是无符号的,(假设您没有编译器对此类事情发出警告)printf 会将其视为 signed int(因为这就是 @987654323 @ 表示)。

    尝试%u 而不是%d

    一旦您解决了这个问题,请意识到在 32 位系统上,int(有符号或无符号)通常只有 32 位大小,因此最多只能保存大约 40 亿个值。如果您想要大于该值的值,则需要更大的类型(如long long)。如果这样做,您还需要将格式字符串更改为"%ull\n"(或"%llu"?我忘了)之类的东西......或者谁知道你会得到什么。

    【讨论】:

      猜你喜欢
      • 2010-09-19
      • 2013-10-02
      • 2015-02-17
      • 1970-01-01
      • 1970-01-01
      • 2012-10-20
      • 2013-02-16
      • 2013-06-02
      • 2013-10-27
      相关资源
      最近更新 更多