【问题标题】:Defining a 128-bit integer in C在 C 中定义一个 128 位整数
【发布时间】:2023-03-10 02:55:02
【问题描述】:

为了表示这个值,我遵循定义:

#define NUM_BITS 128
typedef unsigned char BigInt[NUM_BITS/8];

也就是说,BigInt 类型的值必须由字节数组表示,解释为单个 128 位整数,采用二进制补码并遵循 little-endian 顺序。

例如{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},表示整数值1。

我一直在考虑做一个这样的功能:

void big_val (BigInt res, long val);

这将是带有扩展名的归因。 big_val 函数将 l 提供的值(有符号长整数)分配给 res,正确扩展为 128 位。

我正在考虑,例如,通过y = val & 0xFF000000; 获取最高有效字节,获取数字的符号,然后将该字节再重复 8 次以形成我的数组。但是我怎么能得到代表没有信号的数字的字节呢?

这就是我到目前为止所做的:

void big_val(BigInt res, long val){
    long y;
    y = val&0xFF000000;

    for(int i = 8; i < 16; i++){
        res[i] = y;
    }
}

(对于几分钟前看过这篇文章的人,我不小心删除了它而不是编辑,抱歉)

【问题讨论】:

  • 考虑如果val = 0x80000000会发生什么。
  • 我发现当您想将值保留为基数 10(使其易于输出为文本)时,字节数组很方便,否则使用 uint32_t 数组以便您可以将uint64_t 用于部分乘积、溢出等。但是,通过使用 10^9 而不是 2^32 的基数,仍然可以保持 10 友好。

标签: c type-conversion bit-manipulation 64-bit bit


【解决方案1】:

逐字节分配,一次一个字节。

void BigInt_init_from_long(BigInt res, long val){
    size_t i;
    bool negative = val < 0;
    for (i = 0; i < sizeof(long); ++i) {
        res[i] = val & 0xff;
        val >>= 8;
    }
    for (; i < NUM_BITS/8; ++i) {
        res[i] = negative ? 0xff : 0; // sign extension
    }
 }

【讨论】:

  • 你可能会在其中使用 memcpy 而不是其中的一个 for-loops 和按位逻辑。另一个是 memset 的 if-else。
  • 第二个循环可以换成memset。第一个不能替换为memcpy(在大端机器上)。
  • 很公平。我没有考虑架构可移植性,因为我们正在假设 CHAR_BIT 并且它是二进制补码。我认为他们希望 little-endian 顺序适合他们的 little-endian 系统。
猜你喜欢
  • 2015-10-06
  • 2019-03-15
  • 2013-08-28
  • 2011-07-11
  • 2011-09-18
  • 2013-12-12
  • 1970-01-01
  • 1970-01-01
  • 2015-11-28
相关资源
最近更新 更多