打印无符号长整数时出现问题

3no*_*tur 0 c unsigned types unsigned-integer

我有以下简单的程序,它读取以字符串形式给出的数字并打印它。它适用于小数字,但是当我尝试使用大小为 unsigned long 的数字(例如“18446744073709551615”)时,它不会产生预期的结果。这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void readNumbers(char* numbers, unsigned long numbers_length, unsigned long* number)
{
    char string[numbers_length + 1];
    strncpy(string, numbers + 0, numbers_length);
    *number = strtoul(string, NULL, 10);
}

int main () {

  unsigned long number;

  char* numbers = "18446744073709551615";
  unsigned long numbers_length = strlen(numbers);
  readNumbers(numbers, numbers_length, &number);
  printf("X = %lu \n", number);            // prints 4294967295

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

Edit_1:根据此站点, unsigned long 的最大值为 18446744073709551615。

Edit_2:以下代码适用于我的系统:

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

void readNumbers(char* numbers, int numbers_length, unsigned long long* number)
{
    char string[numbers_length + 1];
    strncpy(string, numbers + 0, numbers_length);
    string[numbers_length] = '\0';
    *number = strtoull(string, NULL, 10);
}


int main () {

  unsigned long long number;

  char* numbers = "18446744073709551615";
  int numbers_length = strlen(numbers);
  readNumbers(numbers, numbers_length, &number);
  printf("X = %llu \n", number);       
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

And*_*zel 5

ISO C 标准仅要求数据类型unsigned long能够表示从0到范围内的数字4,294,967,295

unsigned long在某些平台上,能够表示比 ISO C 标准要求的更大的数字是很常见的。例如,在 64 位 Linux 上,通常能够unsigned long表示最大18,446,744,073,709,551,615. 但在其他平台上,例如 64 位 Microsoft Windows,通常只能unsigned long表示最大为 的数字4,294,967,295,即 ISO C 标准要求的最小数量。

与 相比unsigned long,ISO C 标准保证数据类型unsigned long long能够表示至少18,446,744,073,709,551,615在所有平台上的值。

为了确定unsigned long您的平台上可表示的最大数字,您可以检查宏常量 的值ULONG_MAX

同样,为了确定unsigned long long您的平台上可表示的最大数字,您可以检查宏常量 的值ULLONG_MAX

这是一个示例程序:

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

int main( void )
{
    printf( "  UINT_MAX: %u\n",   UINT_MAX );
    printf( " ULONG_MAX: %lu\n",  ULONG_MAX );
    printf( "ULLONG_MAX: %llu\n", ULLONG_MAX );
}
Run Code Online (Sandbox Code Playgroud)

在使用 MS Visual Studio 的 64 位 Microsoft Windows 上,我得到以下输出:

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

int main( void )
{
    printf( "  UINT_MAX: %u\n",   UINT_MAX );
    printf( " ULONG_MAX: %lu\n",  ULONG_MAX );
    printf( "ULLONG_MAX: %llu\n", ULLONG_MAX );
}
Run Code Online (Sandbox Code Playgroud)

在 64 位 Linux 上,我得到以下输出:

  UINT_MAX: 4294967295
 ULONG_MAX: 4294967295
ULLONG_MAX: 18446744073709551615
Run Code Online (Sandbox Code Playgroud)

UINT_MAX是 中可表示的最大值unsigned int