24-bit int

Biotronic via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Sep 1 15:10:43 PDT 2017


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


More information about the Digitalmars-d-learn mailing list