简体   繁体   中英

Dynamic Integer Size: int64_t, int32_t, uint32_t, etc

I am programming an app that allows a user to select the bit-size of an integer storage and do math with it. They can select 8, 16, 32, or 64 bit storage as signed or unsigned. This is set and changed at runtime, and the app will do math with the given type.

User Interaction Example:

  • Enter 16 bit mode
  • Type 5C
  • Press Plus
  • Type 2A
  • Press Evaluate
    • return { value1.getSigned16() + value2.getSigned16(); }

I would like to avoid programming 8 cases for each operator. I figure a pointer or function-pointer might work well for this. The evaluate method doesn't care what size of an integer I'm using as long as they are both the same. Problem is I can't figure out how to implement this, as the pointers care what kind of variable is returned. I considered using a generic pointer but that doesn't help me when I need to dereference, I still would need the 8 cases.

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...
}

Any thoughts or suggestions on attacking this problem are greatly appreciated.

You cannot have an "arbitrary" return value type for a function. If you want to return a different sized integer, there are a few ways to do it: a union, function overloads, a templates (which would cover the function overloads), or a (and I cringe as I type this) void* return value.

Base on what you've asked, the union would probably be the best fit:

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

The size of this structure will be a minimum of 72 bits (excluding padding and alignment issues), so you could just as easily just return an int64_t and it would cover every smaller integer size.

Always store the value as the largest data type. What's important to you is truncation during arithmetic. You can do that by passing around a full-width value plus the bitwidth (mode).

You don't actually have to do the arithmetic with different types. Just do the computation with 64 bits and cast the result to the bit size.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM