Guest User

Bitmath

a guest
Apr 19th, 2021
187
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.15 KB | None | 0 0
  1. static class Bitmath
  2. {
  3.     // allowed primitive operations: ~(a & b), a == 0, bitshifts by constant values (logical or arithmetic), and reading/writing T[a].
  4.     public static int Nand(this int a, int b) { return ~(a & b); }
  5.     public static bool IsZero(this int a) { return a == 0; }
  6.     public static int LRS(this int a, int b) { return (int)((uint)a >> b); }
  7.  
  8.     // constructed operations
  9.     public static int Not(this int a) { return Nand(a, -1); }
  10.     public static int And(this int a, int b) { return Not(Nand(a, b)); }
  11.     public static int Or(this int a, int b) { return Nand(Not(a), Not(b)); }
  12.     public static int Xor(this int a, int b) { int x = Nand(a, b); return Nand(Nand(a, x), Nand(b, x)); }
  13.  
  14.     public static bool IsNegative(this int a) { return !(a >> 31).IsZero(); }
  15.     public static bool IsPositive(this int a) { return !(a.IsZero() | a.IsNegative()); }
  16.  
  17.     public static int LeftShift(this int a, int b)
  18.     {
  19.         if (!b.And(16).IsZero()) a = a << 16;
  20.         if (!b.And(8).IsZero()) a = a << 8;
  21.         if (!b.And(4).IsZero()) a = a << 4;
  22.         if (!b.And(2).IsZero()) a = a << 2;
  23.         if (!b.And(1).IsZero()) a = a << 1;
  24.         return a;
  25.     }
  26.  
  27.     public static int ArithmeticRightShift(this int a, int b)
  28.     {
  29.         if (!b.And(16).IsZero()) a = a >> 16;
  30.         if (!b.And(8).IsZero()) a = a >> 8;
  31.         if (!b.And(4).IsZero()) a = a >> 4;
  32.         if (!b.And(2).IsZero()) a = a >> 2;
  33.         if (!b.And(1).IsZero()) a = a >> 1;
  34.         return a;
  35.     }
  36.  
  37.     public static int LogicalRightShift(this int a, int b)
  38.     {
  39.         if (!b.And(16).IsZero()) a = a.LRS(16);
  40.         if (!b.And(8).IsZero()) a = a.LRS(8);
  41.         if (!b.And(4).IsZero()) a = a.LRS(4);
  42.         if (!b.And(2).IsZero()) a = a.LRS(2);
  43.         if (!b.And(1).IsZero()) a = a.LRS(1);
  44.         return a;
  45.     }
  46.  
  47.     static int[] RollOffsetTable =
  48.     {
  49.         0, 31, 30, 29, 28, 27, 26, 25,
  50.         24, 23, 22, 21, 20, 19, 18, 17,
  51.         16, 15, 14, 13, 12, 11, 10, 9,
  52.         8, 7, 6, 5, 4, 3, 2, 1
  53.     };
  54.  
  55.     public static int RollLeft(this int a, int b)
  56.     {
  57.         b = b.And(31);
  58.         return a.LeftShift(b).Or(a.LogicalRightShift(RollOffsetTable[b]));
  59.     }
  60.  
  61.     public static int RollRight(this int a, int b)
  62.     {
  63.         b = b.And(31);
  64.         return a.LogicalRightShift(b).Or(a.LeftShift(RollOffsetTable[b]));
  65.     }
  66.  
  67.     public static bool EQ(this int a, int b)
  68.     {
  69.         return a.Sub(b).IsZero();
  70.     }
  71.  
  72.     public static bool NE(this int a, int b)
  73.     {
  74.         return !a.EQ(b);
  75.     }
  76.  
  77.     public static bool GT(this int a, int b)
  78.     {
  79.         if (a.IsPositive() == b.IsPositive())
  80.             return a.Sub(b).IsPositive();
  81.         else
  82.             return a.IsPositive();
  83.     }
  84.  
  85.     public static bool LT(this int a, int b)
  86.     {
  87.         if (a.IsPositive() == b.IsPositive())
  88.             return a.Sub(b).IsNegative();
  89.         else
  90.             return a.IsNegative();
  91.     }
  92.  
  93.     public static bool GE(this int a, int b)
  94.     {
  95.         return !a.LT(b);
  96.     }
  97.  
  98.     public static bool LE(this int a, int b)
  99.     {
  100.         return !a.GT(b);
  101.     }
  102.  
  103.     public static int Add(this int a, int b)
  104.     {
  105.         int c;
  106.         while (!b.IsZero())
  107.         {
  108.             c = a & b;
  109.             a ^= b;
  110.             b = c << 1;
  111.         }
  112.         return a;
  113.     }
  114.  
  115.     public static int Neg(this int a)
  116.     {
  117.         return a.Not().Add(1);
  118.     }
  119.  
  120.     public static int Sub(this int a, int b)
  121.     {
  122.         return a.Add(b.Neg());
  123.     }
  124.  
  125.     public static int Mul(this int a, int b)
  126.     {
  127.         int c = 0;
  128.         while (!b.IsZero())
  129.         {
  130.             if (!b.And(1).IsZero())
  131.                 c = c.Add(a);
  132.             a = a << 1;
  133.             b = b.LRS(1);
  134.         }
  135.         return c;
  136.     }
  137.  
  138.     public static void Divmod(ref int a, ref int b)
  139.     {
  140.         if (a.IsZero() | b.IsZero())
  141.         {
  142.             b = 0;
  143.             return;
  144.         }
  145.         int c = 0;
  146.         if (a.IsPositive() & b.IsPositive())
  147.         {
  148.             while (b.LE(a))
  149.             {
  150.                 c = c.Add(1);
  151.                 a = a.Sub(b);
  152.             }
  153.             b = a;
  154.             a = c;
  155.         }
  156.         else if (a.IsPositive())
  157.         {
  158.             while (a.IsPositive())
  159.             {
  160.                 c = c.Sub(1);
  161.                 a = a.Add(b);
  162.             }
  163.             b = a;
  164.             a = c;
  165.             if (!b.IsZero())
  166.                 a = a.Add(1);
  167.         }
  168.         else if (b.IsNegative())
  169.         {
  170.             while (b.GE(a))
  171.             {
  172.                 c = c.Add(1);
  173.                 a = a.Sub(b);
  174.             }
  175.             b = a;
  176.             a = c;
  177.         }
  178.         else
  179.         {
  180.             while (a.IsNegative())
  181.             {
  182.                 c = c.Sub(1);
  183.                 a = a.Add(b);
  184.             }
  185.             b = a;
  186.             a = c;
  187.             if (!b.IsZero())
  188.                 a = a.Add(1);
  189.         }
  190.     }
  191.  
  192.     public static int Div(this int a, int b)
  193.     {
  194.         Bitmath.Divmod(ref a, ref b);
  195.         return a;
  196.     }
  197.  
  198.     public static int Mod(this int a, int b)
  199.     {
  200.         Bitmath.Divmod(ref a, ref b);
  201.         return b;
  202.     }
  203. }
Advertisement
Add Comment
Please, Sign In to add comment