动态整数大小:int64_t、int32_t、uint32_t 等

Posted

技术标签:

【中文标题】动态整数大小:int64_t、int32_t、uint32_t 等【英文标题】:Dynamic Integer Size: int64_t, int32_t, uint32_t, etc 【发布时间】:2014-01-31 19:46:55 【问题描述】:

我正在编写一个应用程序,它允许用户选择整数存储的位大小并对其进行数学运算。他们可以选择 8、16、32 或 64 位存储作为有符号或无符号。这是在运行时设置和更改的,应用程序将使用给定的类型进行数学运算。

用户交互示例:

进入 16 位模式 5C 型 按加号 2A 型 按评估 return value1.getSigned16() + value2.getSigned16();

我想避免为每个运算符编写 8 个案例。我认为指针或函数指针可能适用于此。评估方法不关心我使用的整数大小,只要它们相同即可。问题是我不知道如何实现这一点,因为指针关心返回的变量类型。我考虑过使用通用指针,但是当我需要取消引用时这对我没有帮助,我仍然需要 8 个案例。

value1.getProperSize() + value2.getProperSize();

// * This obviously won't work
int* getProperSize() 
    if (size == 16) return (int16_t)storageValue;
    if (size == 32) return (int32_t)storageValue;
    // Etc...

非常感谢任何有关解决此问题的想法或建议。

【问题讨论】:

【参考方案1】:

函数不能有“任意”返回值类型。如果你想返回一个不同大小的整数,有几种方法可以做到:联合、函数重载、模板(将覆盖函数重载)或一个(我在输入时畏缩)void*返回值。

根据您的要求,工会可能是最合适的:

struct MyInteger

    uint8_t intSize;
    union
    
        int8_t  Int8;
        int16_t Int16;
        int32_t Int32;
        int64_t Int64;
     intValue;
;

MyInteger getProperSize()

    MyInteger result;
    if (size == 8)
    
        result.intSize = 8;
        result.intvalue.Int8 = someValue;
    
    // ...
    return result;

此结构的大小至少为 72 位(不包括填充和对齐问题),因此您可以轻松地返回一个 int64_t,它将涵盖所有较小的整数大小。

【讨论】:

Nitpick:由于结构填充/对齐,它可能是 128 位。 @Mysticial True ...我会调整措辞以更好地表达我的意思。 谢谢!模板函数似乎是这里的理想解决方案。不太清楚为什么我没有想到。【参考方案2】:

始终将值存储为最大的数据类型。对您来说重要的是算术期间的截断。您可以通过传递全角值加上位宽(模式)来做到这一点。

【讨论】:

【参考方案3】:

您实际上不必对不同类型进行算术运算。只需使用 64 位进行计算并将结果转换为位大小。

【讨论】:

请务必注意,您需要截断每个中间值,而不仅仅是最终结果,以达到与对较小类型执行操作相同的效果。 假设2的补码运算只需要在除法之前截断;加法和乘法自行处理......

以上是关于动态整数大小:int64_t、int32_t、uint32_t 等的主要内容,如果未能解决你的问题,请参考以下文章

int,int32_t,int64_t

int,int32_t,int64_t

在 32 位系统上使用 int64_t 而不是 int32_t 对性能有何影响?

当int32_t是扩展整数类型且int是32位补码标准整数类型时,(INT32_MIN + 1)是什么

Redis数据结构之整数集合

Redis 整数集合