On Friday, 1 September 2017 at 19:39:14 UTC, EntangledQuanta wrote:
Is there a way to create a 24-bit int? One that for all practical purposes acts as such? This is for 24-bit stuff like audio. It would respect endianness, allow for arrays int24[] that work properly, etc.

I haven't looked at endianness beyond it working on my computer. If you have special needs in that regard, consider this a starting point:


struct int24 {
    ubyte[3] _payload;

    this(int x) {
        value = x;
    }

    @property
    int value() {
        int val = *cast(int*)&_payload & 0xFFFFFF;

        if (val & 0x800000) {
            val |= 0xFF000000;
        }

        return val;
    }

    @property
    int value(int x) {
        _payload = (cast(ubyte*)&x)[0..3];
        return value;
    }

    auto opUnary(string op)() {
        static if (op == "++") {
            value = value + 1;
        } else static if (op == "--") {
            value = value - 1;
        } else static if (op == "+") {
            return value;
        } else static if (op == "-") {
            return -value;
        } else static if (op == "~") {
            return ~value;
        } else {
static assert(false, "Unary operator '"~op~"' is not supported by int24.");
        }
    }

    auto opOpAssign(string op)(int x) {
static assert(__traits(compiles, {mixin("value = value "~op~" x;");}), "Binary operator '"~op~"' is not supported by int24.");

        mixin("value = value "~op~" x;");
        return this;
    }

    alias value this;
}

unittest {
    int24[3] a;
    assert(a.sizeof == 9);

    // Max value
    a[1] = 8388607;
    assert(a[1] == 8388607);
    // Test for buffer overflow:
    assert(a[0] == 0);
    assert(a[2] == 0);

    // Overflow
    a[1] = 8388608;
    assert(a[1] == -8388608);
    // Test for buffer overflow:
    assert(a[0] == 0);
    assert(a[2] == 0);

    // negative value
    a[1] = -1;
    assert(a[1] == -1);
    // Test for buffer overflow:
    assert(a[0] == 0);
    assert(a[2] == 0);

    // Unary operators
    a[1] = 0;
    assert(~a[1] == -1);
    a[1]--;
    assert(a[1] == -1);
    assert(-a[1] == 1);
    assert(+a[1] == -1);
    a[1]++;
    assert(a[1] == 0);

    // Binary operators
    a[1] = 0;
    a[1] = a[1] + 1;
    assert(a[1] == 1);
    a[1] += 1;
    assert(a[1] == 2);
    a[1] = a[1] - 1;
    assert(a[1] == 1);
    a[1] -= 1;
    assert(a[1] == 0);

    a[1] = 3;
    a[1] = a[1] * 2;
    assert(a[1] == 6);
    a[1] = a[1] / 2;
    assert(a[1] == 3);
    a[1] *= 2;
    assert(a[1] == 6);
    a[1] /= 2;
    assert(a[1] == 3);
    a[1] = a[1] << 1;
    assert(a[1] == 6);
    a[1] <<= 1;
    assert(a[1] == 12);
    a[1] = a[1] >> 1;
    assert(a[1] == 6);
    a[1] >>= 1;
    assert(a[1] == 3);

    a[1] |= 4;
    assert(a[1] == 7);
    a[1] &= 5;
    assert(a[1] == 5);
    a[1] = a[1] | 2;
    assert(a[1] == 7);
    a[1] = a[1] & 3;
    assert(a[1] == 3);
}

--
  Biotronic

Reply via email to