为什么在Linux上uint64_t定义为unsigned long int,而在Windows上它是unsigned long long int?

0 c linux uint64

我需要使用uint64_tasunsigned long long int因为我需要适应比unsigned long它更大的数字?(两个操作系统都是 64 位),我该如何解决这个问题?这是实现二进制除法的代码: 这是我尝试打印以查看最终函数结果的函数:

void binary_div(s21_big_decimal *value_1, s21_big_decimal value_2, s21_big_decimal *result) {
  init_s21_decimal(result);
  s21_big_decimal Q;
  s21_big_decimal R;
  int scaleDiv = -1;
  do {
    init_s21_decimal(&R);
    init_s21_decimal(&Q);
    scaleDiv++;
    int lastBit = (SIZE_BIG_DECIMAL - 1) * 32 - 1;
    int currentBit = get_bit_big(*value_1, lastBit);
    while (currentBit == 0 && lastBit >= 0) {
      currentBit = get_bit_big(*value_1, lastBit);
      if (currentBit == 0) lastBit--;
    }
    for (int i = lastBit; i >= 0; i--) {
      change_left_big(&R, 1);
      set_bit_big(&R, 0, get_bit_big(*value_1, i));
      if (is_less_or_equal_big(value_2, R)) {
        s21_big_decimal res = {0};
        init_s21_decimal(&res);
        s21_sub_big(R, value_2, &res);
        init_s21_decimal(&R);
        copy_bits(res, &R);
        set_bit_big(&Q, i, 1);
      }
    }
    if (scaleDiv > 0) {
      mul_10_big(result);
    }
    s21_big_decimal res;
    init_s21_decimal(&res);
    add_big(*result, Q, &res);
    copy_bits(res, result);
    if (!is_zero_big(R)) {
      init_s21_decimal(value_1);
      mul_10_big(&R);
      copy_bits(R, value_1);
    }
  } while (!is_zero_big(R) && scaleDiv < 28);
  set_scale_big(result, scaleDiv);
  for (int i = 0; i < 7; i++) {
    printf("%lX ", result->bits[i]);
  }
  printf("\n");
}
Run Code Online (Sandbox Code Playgroud)

我使用位,这里是函数 mul_10_big 的示例:

void binary_div(s21_big_decimal *value_1, s21_big_decimal value_2, s21_big_decimal *result) {
  init_s21_decimal(result);
  s21_big_decimal Q;
  s21_big_decimal R;
  int scaleDiv = -1;
  do {
    init_s21_decimal(&R);
    init_s21_decimal(&Q);
    scaleDiv++;
    int lastBit = (SIZE_BIG_DECIMAL - 1) * 32 - 1;
    int currentBit = get_bit_big(*value_1, lastBit);
    while (currentBit == 0 && lastBit >= 0) {
      currentBit = get_bit_big(*value_1, lastBit);
      if (currentBit == 0) lastBit--;
    }
    for (int i = lastBit; i >= 0; i--) {
      change_left_big(&R, 1);
      set_bit_big(&R, 0, get_bit_big(*value_1, i));
      if (is_less_or_equal_big(value_2, R)) {
        s21_big_decimal res = {0};
        init_s21_decimal(&res);
        s21_sub_big(R, value_2, &res);
        init_s21_decimal(&R);
        copy_bits(res, &R);
        set_bit_big(&Q, i, 1);
      }
    }
    if (scaleDiv > 0) {
      mul_10_big(result);
    }
    s21_big_decimal res;
    init_s21_decimal(&res);
    add_big(*result, Q, &res);
    copy_bits(res, result);
    if (!is_zero_big(R)) {
      init_s21_decimal(value_1);
      mul_10_big(&R);
      copy_bits(R, value_1);
    }
  } while (!is_zero_big(R) && scaleDiv < 28);
  set_scale_big(result, scaleDiv);
  for (int i = 0; i < 7; i++) {
    printf("%lX ", result->bits[i]);
  }
  printf("\n");
}
Run Code Online (Sandbox Code Playgroud)

chq*_*lie 5

uint64_tunsigned longLinux 和 macOS 上,因为该类型unsigned long有 64 位,因此不需要使用具有更大级别的类型,尽管unsigned long long后面的类型也有 64 位。

在 Windows 上,uint64_t无法进行类型定义,unsigned long因为由于遗留原因,Microsoft 选择保留unsigned long为 32 位类型,即使在其 64 位 ABI 上也是如此。

如果您需要处理大于 的数字4294967295,则确实不应使用unsigned long可能限制为 32 位的数字。使用uint64_t恰好 64 位或unsigned long long至少 64 位是正确的选择。uint64_t可能并非在所有平台上都可用,但在您的目标上是可用的,并且您不太可能遇到不可用的平台。

uint64_t对于您的目的而言,是否类型定义unsigned long并不unsigned long long重要,因为它始终是 64 位。

更改类型uint64_t不是一个选项,因为在不同模块中使用不同的定义可能会出现潜在的未定义行为。

如果您在应用程序中一致地使用整数类型,那么uint64_t在需要 64 位无符号类型的任何地方使用应该不会造成问题。

对于读取和打印,您可以使用以下中定义的标准宏<inttypes.h>

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

int main(int argc, char *argv[]) {
    uint64_t x;
    if (argc > 1 && sscanf(argv[1], "%"SCNu64"", &x) == 1) {
        printf("%16"PRIx64"\n", x);
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果您愿意,可以这样使用strtoulland :printf

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

int main(int argc, char *argv[]) {
    char buf[100];
    uint64_t x;
    if (argc > 1) {
        x = strtoul(argv[1], NULL, 10);
        printf("%16llx"\n", (unsigned long long)x);
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

您还可以将自己的类型定义u64_tunsigned long longand use%llu%llxinscanfprintflike 函数的 typedef,而无需额外的强制转换。

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

typedef unsigned long long u64_t;  // assuming 64-bit

int main(int argc, char *argv[]) {
    u64_t x;
    if (argc > 1 && sscanf(argv[1], "%llu", &x) == 1) {
        printf("%16llx\n", x);
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

或者您可以简单地unsigned long long在任何地方使用。