Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C语言中的12字节整数_C_X86_Arm - Fatal编程技术网

C语言中的12字节整数

C语言中的12字节整数,c,x86,arm,C,X86,Arm,我需要一个12字节或96位无符号整数来对它进行简单的算术运算。我尝试了以下方法,因为C中没有内置的数据类型 typedef struct { __uint128_t i:96; __uint128_t j:96; }; __uint128_t __add(__uint128_t a, __uint128_t b) { return a + b; } 但一些较旧版本的GCC编译器版本不支持这一点 因此,需要具有交叉编译支持的通用实现 根据这里提到的答案- 3个整数的数组,作为替

我需要一个12字节或96位无符号整数来对它进行简单的算术运算。我尝试了以下方法,因为C中没有内置的数据类型

typedef struct
{
    __uint128_t i:96;
    __uint128_t j:96;
};
__uint128_t __add(__uint128_t a, __uint128_t b) { return a + b; }
但一些较旧版本的GCC编译器版本不支持这一点

因此,需要具有交叉编译支持的通用实现

根据这里提到的答案-

3个整数的数组,作为替代解决方案?怎么做


非常感谢任何进一步的帮助

如果需要使用通用解决方案,可以尝试创建包含64位整数和另一个32位整数的结构。然后重新定义一些需要执行的操作


一个经典的例子是struct timespec,它有两个整数,一个表示秒,一个表示纳秒。

最简单的方法是使用uint128\t,除非它在您的平台上不可用,或者使用的额外存储不知何故对您是个问题

也就是说,您可以使用问题中提到的三个uint32的数组。但是你需要自己实现所有的基本算术运算,正如你所看到的,它会变得非常复杂!下面是一个刚刚实现的加法示例

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

typedef struct uint96_t 
{
    uint32_t value[3];
}uint96_t;

uint96_t add_uint96(uint96_t x, uint96_t y)
{
    uint96_t result = {0};
    unsigned int carry = 0;
    int i = sizeof(x.value)/sizeof(x.value[0]);
    /* Start from LSB */
    while(i--)
    {
        uint64_t tmp = (uint64_t)x.value[i] + y.value[i] + carry;    
        result.value[i] = (uint32_t)tmp;
        /* Remember the carry */
        carry = tmp >> 32;
    }
    return result;
}

void print_uint96(char *str, uint96_t x)
{
    printf("%s = %08x%08x%08x\r\n", str, x.value[0], x.value[1], x.value[2]);
}

int main(void)
{
    uint96_t x = {0x0FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF};
    uint96_t y = {0x00, 0x00, 0x01};
    uint96_t r = add_uint96(x, y);
    print_uint96("x", x);
    print_uint96("y", y);
    print_uint96("result", r);
    return 0;
}

在struct timespec的帮助下,我做了如下工作:


使用GMP多精度算术库怎么样?为什么需要96位整数并对其进行算术运算?您需要解决的真正问题是什么?如果需要存储纳秒值,则将整秒存储在64位整数中,将小数部分存储在32位整数中。这方面的算法并不难。这就是struct timespec在实际中所做的。您必须决定是否需要两个纳秒时间值之间的有符号值负间隔。处理符号位更为棘手,可能需要在64位中使用1位符号和63位大小字段,持续整秒钟。@Thulasivegalam,您需要交叉编译到哪个96位计算机。。。说真的,只需使用一个bigint库。@Lundin:像这样的多精度库是一个极大的不必要的膨胀。元数据本身(例如位数、空间量)将比数据成本高,并且由于不必要的条件,性能将下降。长双实浮点类型,通常映射为扩展精度浮点数字格式。实际属性未指定。它可以是x86扩展精度浮点格式80位,但在内存中通常是96位或128位(带填充字节)、非IEEE双精度128位、IEEE 754四精度浮点格式128位,或与双精度相同。有关详细信息,请参阅关于long double的文章。@Thulasivegalam:在某些针对x86-64的C实现中,long double是80位x87类型。e、 g.Linux/MacOS编译器。在Windows上,long double与64位double MSVC和gcc/clang/ICC Windows相同。您不太可能不想要数据的扩展精度FP。@Thulasivegalam如果您想要特定数量的存储,我认为浮点不是正确的方法。它可能涉及更复杂的问题,并且不能保证提供所需的精度位数。就像上面提到的Peter一样,平台之间的变量甚至比整数更大。顺便说一句,C11指定tv_nsec是一个有符号长的,所以是的,减法可以使其为负数,而不是换行为高无符号值。
struct timespec
__timespec_add (const struct timespec start,
                      const struct timespec end)
{
  struct timespec sum;
  sum.tv_sec = start.tv_sec + end.tv_sec;
  sum.tv_nsec = start.tv_nsec + end.tv_nsec;
  if (sum.tv_nsec >= 1000000000)
  {
     ++sum.tv_sec;
     sum.tv_nsec = sum.tv_nsec - 1000000000;
  }
  return sum;
}

struct timespec
__timespec_diff (const struct timespec start,
                      const struct timespec end)
{
  struct timespec diff;
  diff.tv_sec = start.tv_sec - end.tv_sec;
  diff.tv_nsec = start.tv_nsec - end.tv_nsec;
  if (diff.tv_nsec < 0)
  {
      --diff.tv_sec;
      diff.tv_nsec = diff.tv_nsec + 1000000000;
  }
 return diff;
}