创建自己的变量类型

时间:2015-09-15 15:37:20

标签: c

是否可以在C / C ++中创建自定义类型的变量?我想要像#34; super long int"这样占用让我们说40个字节,并允许相同的操作,就像在通常的int中一样。 (+, - ,/,%,<,>等等。)

2 个答案:

答案 0 :(得分:3)

对于类似的东西没有任何内置,至少在C中没有。你需要使用像GMP这样的大数字库。它不允许使用正常的运算符集,但它可以处理任意大的数字。

编辑:

如果你的目标是C ++,GMP确实有重载的运算符,这些运算符允许你使用标准的运算符集,就像使用常规的int一样。有关详细信息,请参阅manual

答案 1 :(得分:1)

某些CPU支持使用非常大的数字。使用x86 / 64架构上的SSE,您可以实现128位值(16字节),可以正常计算。 使用AVX,此限制扩展到256位(32字节)。即将推出的AVX-512扩展应该具有512位(64字节),从而实现超大型#34;整数。

但这些扩展有两点需要注意:

  1. 编译器必须支持它(例如,GCC使用immintrin.h进行AXV支持,使用xmmintrin.h进行SSE支持。或者你可以尝试通过内联汇编程序实现抽象,但汇编程序必须理解这些(据我所知,GCC使用AS)。
  2. 运行已编译代码的计算机必须支持这些说明。如果CPU不支持AVX或SSE(取决于你想要做什么),应用程序将因这些指令而崩溃,因为CPU不理解它们。
  3. AVX / SSE用于memsetmemcpy等的实现,因为它们还允许您通过一个很好的协议减少内存访问(请记住,当您的缓存行将被加载到缓存一次,加载到它仍然需要一些周期,AVX / SSE也可以帮助您消除这些成本中的大部分成本。)

    这是一个工作示例(使用GCC 4.9.3编译,您必须将-mavx添加到编译器选项中):

    #include <immintrin.h>
    #include <stdint.h>
    #include <stdio.h>
    
    int main(void)
    {
            size_t i;
    
            /*********************************************************************
            **Hack-ish way to ensure that malloc's alignment does not screw with
            **us. On this box it aligns to 0x10 bytes, but AVX needs 0x20.
            *********************************************************************/
    #define AVX_BASE (0x20ULL)
    
            uint64_t*real_raw = malloc(128);
            uint64_t*raw = (uint64_t*)((uintptr_t)real_raw + (AVX_BASE - ((uintptr_t)real_raw % AVX_BASE)));
    
            __m256i value = _mm256_setzero_si256();
    
            for(i = 0;i < 10;i++)
            {
                    /*No special function here to do the math.*/
                    value += i * i;
    
                    /*************************************************************
                    **Extract the value from the register and print the last
                    **byte.
                    *************************************************************/
                    _mm256_store_si256((__m256i*)raw,value);
                    printf("%lu\n",raw[0]);
            }
    
            _mm256_store_si256((__m256i*)raw,value);
            printf("End: %lu\n",raw[0]);
    
            free(real_raw);
            return 0;
    }