You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

x86-64平台uint64_t跨OS定义差异及适配方案求助

x86-64架构下Linux与Windows的uint64_t定义差异及兼容方案

一、uint64_t定义差异的原因

两大平台的差异源于遵循的C语言数据模型不同:

  • Linux等类Unix系统在x86-64架构下采用LP64模型:long和指针类型为64位,int为32位,因此unsigned long int刚好满足64位无符号整数的要求,被用来定义uint64_t。
  • Windows在x86-64架构下采用LLP64模型:为兼容32位旧程序,保留了long的32位长度,仅将long long和指针扩展为64位,因此只能用unsigned long long int定义uint64_t。

二、跨平台将uint64_t按unsigned long long使用的方案

无需修改系统头文件中的uint64_t定义,通过以下方式实现跨平台兼容:

  • 直接显式使用unsigned long long:如果代码需要固定64位无符号类型,直接写unsigned long long而非依赖uint64_t,该类型在两个平台上均为64位。
  • 封装自定义类型别名:统一代码中的64位无符号类型,避免平台差异:
#if defined(_WIN64) || defined(__linux__)
typedef unsigned long long my_uint64;
#endif

后续代码中统一使用my_uint64即可保证跨平台的64位长度。

  • 修正代码潜在风险:检查代码中依赖平台类型的部分,比如你提供的div_10_big函数中,dec->bits[i] += remained << 32的操作,如果bits成员是unsigned long,在Windows下会因32位长度导致溢出风险。建议将s21_big_decimal的bits数组直接定义为unsigned long long类型,彻底规避平台差异。

三、相关实现代码

二进制除法核心函数

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");
}

位操作辅助函数

int mul_10_big(s21_big_decimal *dec)
{
  s21_big_decimal temp = *dec;
  for (int i = 0; i < SIZE_BIG_DECIMAL - 1; i++)
  {
    temp.bits[i] *= 10;
  }
  temp.scale++;
  int overflowed = 0;
  if (getoverflow(&temp))
  {
    overflowed = 1;
  }
  else
  {
    *dec = temp;
  }
  return overflowed;
}

int div_10_big(s21_big_decimal *dec)
{
  uint64_t remained = 0;
  for (int i = SIZE_BIG_DECIMAL - 2; i >= 0; i--)
  {
    dec->bits[i] += remained << 32;
    remained = dec->bits[i] % 10;
    dec->bits[i] /= 10;
  }
  dec->scale--;
  return remained;
}

int add_big(s21_big_decimal big_dec1, s21_big_decimal big_dec2,
            s21_big_decimal *result)
{
  int res = 0;
  normalization_big(&big_dec1, &big_dec2);
  for (int i = 0; i < SIZE_BIG_DECIMAL - 1; i++)
  {
    result->bits[i] += big_dec1.bits[i] + big_dec2.bits[i];
    getoverflow(result);
  }
  return res;
}

内容的提问来源于stack exchange,提问作者laptop22

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 02:44:51