Last active
August 29, 2015 13:57
-
-
Save iarovyi/9779036 to your computer and use it in GitHub Desktop.
BitwiseMath - fun with bitwise operations
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Diagnostics.Contracts; | |
using System.Linq; | |
using System.Runtime.CompilerServices; | |
using System.Runtime.ConstrainedExecution; | |
namespace SortingExtensions.Demo.Trash | |
{ | |
/* | |
Another handy syntax | |
public enum HostProtectionResource | |
{ | |
None = 0x00000000, | |
//-------------------------------- | |
Synchronization = 0x00000001, | |
SharedState = 0x00000002, | |
ExternalProcessMgmt = 0x00000004, | |
SelfAffectingProcessMgmt = 0x00000008, | |
ExternalThreading = 0x00000010, | |
SelfAffectingThreading = 0x00000020, | |
SecurityInfrastructure = 0x00000040, | |
UI = 0x00000080, | |
MayLeakOnAbort = 0x00000100, | |
//--------------------------------- | |
All = 0x000001ff, | |
} | |
*/ | |
//TODO add method for enums | |
//http://inf.e-alekseev.ru/text/Schisl_perevod.html | |
public static class BitwiseMath | |
{ | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
private static bool GetBit(int n, int bitIndex) | |
{ | |
Contract.Requires(bitIndex >= 0 && bitIndex < 32); | |
return (n & (1 << bitIndex)) != 0; | |
} | |
public static char[] GetBytes(int n) | |
{ | |
var chars = new char[32]; | |
for (int i = 0; i < 32; i++) | |
{ | |
chars[i] = GetBit(n, i) ? '1' : '0'; | |
} | |
return chars; | |
} | |
//TODO: new BitArray() | |
public static string GetPretifiedBytesString(int n) | |
{ | |
Contract.Ensures(Contract.Result<string>().Replace(" ", "") == (n > 0 ? "0" : "1") + Convert.ToString(n, 2).PadLeft(31, '0')); | |
char[] chars = GetBytes(n), | |
pretified = new char[32 + 8]; | |
if (BitConverter.IsLittleEndian) | |
{ | |
chars = chars.Reverse().ToArray(); | |
} | |
pretified[0] = chars[0]; | |
pretified[1] = ' '; | |
pretified[2] = chars[1]; | |
pretified[3] = chars[2]; | |
pretified[4] = chars[3]; | |
for (int i = 4, j = 5; i < 32; i = i + 4, j = j + 5) | |
{ | |
pretified[j] = ' '; | |
pretified[j + 1] = chars[i]; | |
pretified[j + 2] = chars[i + 1]; | |
pretified[j + 3] = chars[i + 2]; | |
pretified[j + 4] = chars[i + 3]; | |
} | |
return new string(pretified); | |
} | |
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] | |
private static int GetMedian(int low, int hi) | |
{ | |
return low + (hi - low >> 1); | |
} | |
public static int TwoInPow(int pow) | |
{ | |
if (pow > 30) | |
throw new ArgumentOutOfRangeException("pow"); | |
return 1 << pow; | |
} | |
public static int MultiplyNumberByTwoInPow(int number, int pow) | |
{ | |
if (pow > 30) | |
throw new ArgumentOutOfRangeException("pow"); | |
return number << pow; | |
/* x * (2 ^ n) | |
return (number * (int)Math.Pow(2, pow)); | |
x << 1 = x * 2 | |
x << 2 = x * 4 | |
x << 3 = x * 8*/ | |
} | |
public static int DivideNumberByTwoInPow(int number, int pow) | |
{ | |
if (pow > 30) | |
throw new ArgumentOutOfRangeException("pow"); | |
return number >> pow; | |
/*number / (2 ^ pow) | |
return (number / (int)Math.Pow(2, pow)); | |
x >> 1 = x / 2 | |
x >> 2 = x / 4 | |
x >> 3 = x / 8*/ | |
} | |
#region Multiply | |
public static int Multiply(int a, int b) | |
{ | |
int r = 0; | |
while (b != 0) | |
{ | |
var temp = b & 1; | |
if (temp != 0) | |
{ | |
r = r + a; | |
} | |
a = a << 1; | |
b = b >> 1; | |
} | |
return r; | |
} | |
#endregion | |
#region Divide | |
public static int DivideBy3(int num) | |
{ | |
int sum = 0; | |
while (num > 3) | |
{ | |
sum = Add(num >> 2, sum); | |
num = Add(num >> 2, num & 3); | |
} | |
if (num == 3) | |
sum = Add(sum, 1); | |
return sum; | |
} | |
public static int Divide(int dividend, int divisor) | |
{ | |
return Divide(dividend, divisor, divisor, 0); | |
} | |
private static int Divide(int dividend, int divisor, int origdiv, int remainder) | |
{ | |
int quotient = 1; | |
if (dividend == divisor) | |
{ | |
return 1; | |
} | |
if (dividend < divisor) | |
{ | |
return 0; | |
} | |
while (divisor <= dividend) | |
{ | |
divisor = divisor << 1; | |
quotient = quotient << 1; | |
} | |
if (dividend < divisor) | |
{ | |
divisor >>= 1; | |
quotient >>= 1; | |
} | |
quotient = quotient + Divide(dividend - divisor, origdiv, origdiv, remainder); | |
return quotient; | |
} | |
#endregion | |
#region Add | |
public static int AddRecursive(int x, int y) | |
{ | |
if (y == 0) | |
{ | |
return x; | |
} | |
return AddRecursive(x ^ y, (x & y) << 1); | |
} | |
public static int Add(int x, int y) //((a & b) << 1) | (a ^ b); - Simple but wrong implementation | |
{ | |
// Iterate till there is no carry | |
while (y != 0) | |
{ | |
int carry = x & y; // carry now contains common set bits of x and y | |
x = x ^ y; // Sum of bits of x and y where at least one of the bits is not set | |
y = carry << 1; // Carry is shifted by one so that adding it to x gives the required sum | |
} | |
return x; | |
} | |
#endregion | |
#region Substract | |
public static int SubtractRecursive(int x, int y) | |
{ | |
if (y == 0) | |
{ | |
return x; | |
} | |
int sub = x ^ y, | |
subCarry = (sub & y) << 1; | |
return SubtractRecursive(sub, subCarry); | |
} | |
#endregion | |
} | |
} |
string str = Regex.Replace(input, "#(.)\1(.)\2(.)\3", "#$1$2$3");
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
rows = rows.OrderBy(x => System.Web.UI.DataBinder.Eval(x, sidx)).ToList();