public object ReverseBits(object value) { if (value == null) { return(0); } switch (value) { case byte vbyte: return(ReverseBytes[vbyte]); case sbyte vsbyte: return(ReverseBytes[(byte)vsbyte]); case short vshort: return((short)((ReverseBytes[(byte)vshort] << 8) | ReverseBytes[(byte)(vshort >> 8)])); case ushort vushort: return((short)((ReverseBytes[(byte)vushort] << 8) | ReverseBytes[(byte)(vushort >> 8)])); case int vint: return((ReverseBytes[(byte)vint] << 24) | (ReverseBytes[(byte)(vint >> 8)] << 16) | (ReverseBytes[(byte)(vint >> 16)] << 8) | ReverseBytes[(byte)(vint >> 24)]); case uint vuint: return((ReverseBytes[(byte)vuint] << 24) | (ReverseBytes[(byte)(vuint >> 8)] << 16) | (ReverseBytes[(byte)(vuint >> 16)] << 8) | ReverseBytes[(byte)(vuint >> 24)]); case long vlong: return(((long)ReverseBytes[(byte)vlong] << 56) | ((long)ReverseBytes[(byte)(vlong >> 8)] << 48) | ((long)ReverseBytes[(byte)(vlong >> 16)] << 40) | ((long)ReverseBytes[(byte)(vlong >> 24)] << 32) | ((long)ReverseBytes[(byte)(vlong >> 32)] << 24) | ((long)ReverseBytes[(byte)(vlong >> 40)] << 16) | ((long)ReverseBytes[(byte)(vlong >> 48)] << 8) | (long)ReverseBytes[(byte)(vlong >> 56)]); case ulong vulong: return(((ulong)ReverseBytes[(byte)vulong] << 56) | ((ulong)ReverseBytes[(byte)(vulong >> 8)] << 48) | ((ulong)ReverseBytes[(byte)(vulong >> 16)] << 40) | ((ulong)ReverseBytes[(byte)(vulong >> 24)] << 32) | ((ulong)ReverseBytes[(byte)(vulong >> 32)] << 24) | ((ulong)ReverseBytes[(byte)(vulong >> 40)] << 16) | ((ulong)ReverseBytes[(byte)(vulong >> 48)] << 8) | (ulong)ReverseBytes[(byte)(vulong >> 56)]); case BigInteger bigInt: { var array = bigInt.ToByteArray(); int mid = array.Length / 2; for (int i = 0; i < mid; i++) { var highIndex = array.Length - i - 1; var high = ReverseBytes[array[highIndex]]; var low = ReverseBytes[array[i]]; array[i] = high; array[highIndex] = low; } if ((array.Length & 1) != 0) { array[mid] = ReverseBytes[array[mid]]; } return(new BigInteger(array)); } case KalkVector vector: var outVector = vector.Clone(); for (int i = 0; i < vector.Length; i++) { var result = ReverseBits(vector.GetComponent(i)); outVector.SetComponent(i, result); } return(outVector); case KalkNativeBuffer nativeBuffer: { var buffer = new KalkNativeBuffer(nativeBuffer.Count); int mid = nativeBuffer.Count / 2; for (int i = 0; i < mid; i++) { var highIndex = nativeBuffer.Count - i - 1; var high = ReverseBytes[nativeBuffer[highIndex]]; var low = ReverseBytes[nativeBuffer[i]]; buffer[i] = high; buffer[highIndex] = low; } if ((buffer.Count & 1) != 0) { buffer[mid] = ReverseBytes[nativeBuffer[mid]]; } return(buffer); } case KalkMatrix matrix: var uintMatrix = new KalkMatrix <int>(matrix.RowCount, matrix.ColumnCount); for (int y = 0; y < matrix.RowCount; y++) { uintMatrix.SetRow(y, (KalkVector <int>)ReverseBits(matrix.GetRow(y))); } return(uintMatrix); default: throw new ArgumentException($"The type {Engine.GetTypeName(value)} is not supported.", nameof(value)); } }
public object FirstBitHigh(object value) { if (value == null) { return(0); } switch (value) { case sbyte vsbyte: { var result = BitOperations.LeadingZeroCount((byte)(uint)vsbyte); if (result >= 32) { return(-1); } return(result - 24); } case byte vbyte: { var result = BitOperations.LeadingZeroCount(vbyte); if (result >= 32) { return(-1); } return(result - 24); } case short vshort: { var result = BitOperations.LeadingZeroCount((ushort)(uint)vshort); if (result >= 32) { return(-1); } return(result - 16); } case ushort vushort: { var result = BitOperations.LeadingZeroCount((uint)vushort); if (result >= 32) { return(-1); } return(result - 16); } case int vint: { var result = BitOperations.LeadingZeroCount((uint)vint); if (result >= 32) { return(-1); } return(result); } case uint vuint: { var result = BitOperations.LeadingZeroCount((uint)vuint); if (result >= 32) { return(-1); } return(result); } case long vlong: { var result = BitOperations.LeadingZeroCount((ulong)vlong); if (result >= 64) { return(-1); } return(result); } case ulong vulong: { var result = BitOperations.LeadingZeroCount((ulong)vulong); if (result >= 64) { return(-1); } return(result); } case KalkVector vector: var uintVector = new KalkVector <int>(vector.Length); for (int i = 0; i < vector.Length; i++) { var result = FirstBitHigh(vector.GetComponent(i)); if (result is int intv) { uintVector[i] = (int)intv; } else { uintVector[i] = (int)(long)result; } } return(uintVector); case KalkMatrix matrix: var uintMatrix = new KalkMatrix <int>(matrix.RowCount, matrix.ColumnCount); for (int y = 0; y < matrix.RowCount; y++) { uintMatrix.SetRow(y, (KalkVector <int>)FirstBitHigh(matrix.GetRow(y))); } return(uintMatrix); default: throw new ArgumentException($"The type {Engine.GetTypeName(value)} is not supported.", nameof(value)); } }
public object FirstBitLow(object value) { if (value == null) { return(0); } switch (value) { case sbyte vsbyte: { var result = BitOperations.TrailingZeroCount(vsbyte); if (result >= 32) { return(-1); } return(result); } case byte vbyte: { var result = BitOperations.TrailingZeroCount(vbyte); if (result >= 32) { return(-1); } return(result); } case short vshort: { var result = BitOperations.TrailingZeroCount(vshort); if (result >= 32) { return(-1); } return(result); } case ushort vushort: { var result = BitOperations.TrailingZeroCount(vushort); if (result >= 32) { return(-1); } return(result); } case int vint: { var result = BitOperations.TrailingZeroCount(vint); if (result >= 32) { return(-1); } return(result); } case uint vuint: { var result = BitOperations.TrailingZeroCount(vuint); if (result >= 32) { return(-1); } return(result); } case long vlong: { var result = BitOperations.TrailingZeroCount(vlong); if (result >= 64) { return(-1); } return(result); } case ulong vulong: { var result = BitOperations.TrailingZeroCount(vulong); if (result >= 64) { return(-1); } return(result); } case BigInteger bigint: if (bigint >= 0 && bigint <= ulong.MaxValue) { var result = BitOperations.TrailingZeroCount((ulong)bigint); if (result >= 64) { return(-1); } return(result); } else if (bigint < 0 && bigint >= long.MinValue) { var result = BitOperations.TrailingZeroCount((long)bigint); if (result >= 64) { return(-1); } return(result); } // TODO: implement this case for bigint goto default; case KalkVector vector: var uintVector = new KalkVector <int>(vector.Length); for (int i = 0; i < vector.Length; i++) { var result = FirstBitLow(vector.GetComponent(i)); if (result is int intv) { uintVector[i] = (int)intv; } else { uintVector[i] = (int)(long)result; } } return(uintVector); case KalkMatrix matrix: var uintMatrix = new KalkMatrix <int>(matrix.RowCount, matrix.ColumnCount); for (int y = 0; y < matrix.RowCount; y++) { uintMatrix.SetRow(y, (KalkVector <int>)FirstBitLow(matrix.GetRow(y))); } return(uintMatrix); default: throw new ArgumentException($"The type {Engine.GetTypeName(value)} is not supported.", nameof(value)); } }
public object CountBits(object value) { if (value == null) { return(0); } switch (value) { case byte vbyte: return(BitOperations.PopCount(vbyte)); case sbyte vsbyte: return(BitOperations.PopCount((uint)vsbyte)); case short vshort: return(BitOperations.PopCount((uint)vshort)); case ushort vushort: return(BitOperations.PopCount((uint)vushort)); case int vint: return(BitOperations.PopCount((uint)vint)); case uint vuint: return(BitOperations.PopCount((uint)vuint)); case long vlong: return(BitOperations.PopCount((ulong)vlong)); case ulong vulong: return(BitOperations.PopCount((ulong)vulong)); case BigInteger bigInt: { // TODO: not optimized, should use 64 bits var array = bigInt.ToByteArray(); int count = 0; for (int i = 0; i < array.Length; i++) { count += BitOperations.PopCount(array[i]); } return(count); } case KalkVector vector: var uintVector = new KalkVector <int>(vector.Length); for (int i = 0; i < vector.Length; i++) { var result = CountBits(vector.GetComponent(i)); if (result is int intv) { uintVector[i] = (int)intv; } else { uintVector[i] = (int)(long)result; } } return(uintVector); case KalkNativeBuffer nativeBuffer: { var span = nativeBuffer.AsSpan(); int count = 0; for (int i = 0; i < span.Length; i++) { count += BitOperations.PopCount(span[i]); } return(count); } case KalkMatrix matrix: var uintMatrix = new KalkMatrix <int>(matrix.RowCount, matrix.ColumnCount); for (int y = 0; y < matrix.RowCount; y++) { uintMatrix.SetRow(y, (KalkVector <int>)CountBits(matrix.GetRow(y))); } return(uintMatrix); default: throw new ArgumentException($"The type {Engine.GetTypeName(value)} is not supported.", nameof(value)); } }