/// <summary> /// Adds two bit strings together - e.g. "11" (3) + 111 (7) = 1010 (10). /// Similar to <see cref="AddWithModulo(NIST.CVP.ACVTS.Libraries.Math.BitString,NIST.CVP.ACVTS.Libraries.Math.BitString,int)"/>, but without truncation. /// </summary> /// <param name="left"></param> /// <param name="right"></param> /// <returns></returns> public static BitString BitStringAddition(BitString left, BitString right) { left = left.GetDeepCopy(); right = right.GetDeepCopy(); PadShorterBitStringWithZeroes(ref left, ref right); int length = left.BitLength; // they are now of equal length, doesn't matter which is used int carry = 0; List <bool> bits = new List <bool>(); // Add all bits one by one for (int i = 0; i < length; i++) { int firstBit = left.Bits[i] ? 1 : 0; int secondBit = right.Bits[i] ? 1 : 0; bool sum = (firstBit ^ secondBit ^ carry) == 1; bits.Add(sum); carry = (firstBit & secondBit) | (secondBit & carry) | (firstBit & carry); } // if overflow, then add a bit if (carry == 1) { bits.Add(true); } return(new BitString(new BitArray(bits.ToArray()))); }
public static BitString AND(BitString sourceLeft, BitString sourceRight) { BitString left = sourceLeft.GetDeepCopy(); BitString right = sourceRight.GetDeepCopy(); BitString.PadShorterBitStringWithZeroes(ref left, ref right); BitArray andArray = left.Bits.And(right.Bits); return(new BitString(new BitArray(andArray))); }
public static BitString OR(BitString sourceLeft, BitString sourceRight) { // Deep copies to avoid accidental assignment BitString left = sourceLeft.GetDeepCopy(); BitString right = sourceRight.GetDeepCopy(); BitString.PadShorterBitStringWithZeroes(ref left, ref right); BitArray orArray = left.Bits.Or(right.Bits); return(new BitString(new BitArray(orArray))); }
public static BitString XOR(BitString sourceLeft, BitString sourceRight) { // Deep copies to avoid accidental assignment BitString left = sourceLeft.GetDeepCopy(); BitString right = sourceRight.GetDeepCopy(); // Pad shorter BitString with 0s to match longer BitString length BitString.PadShorterBitStringWithZeroes(ref left, ref right); BitArray xorArray = left.Bits.Xor(right.Bits); return(new BitString(new BitArray(xorArray))); }
/// <summary> /// Rotates bits in the MSB direction. Rotate puts the bits that 'fall off' onto the end. /// </summary> /// <param name="shiftBitString">BitString to rotate</param> /// <param name="distance">Amount the bits to rotate.</param> /// <returns>Rotated BitString</returns> public static BitString MSBRotate(BitString shiftBitString, int distance) { var bits = shiftBitString.GetDeepCopy().GetBitsMSB(); var bitLength = shiftBitString.BitLength; var newBits = new bool[bitLength]; for (var i = 0; i < bitLength; i++) { newBits[i] = bits[(i + distance) % bitLength]; } Array.Reverse(newBits); return(new BitString(new BitArray(newBits))); }
/// <summary> /// Adds two BitStrings and truncates the result to fit within the limit. /// </summary> /// <param name="left"></param> /// <param name="right"></param> /// <param name="moduloPower">Amount of bits kept in the result.</param> /// <returns></returns> public static BitString AddWithModulo(BitString left, BitString right, int moduloPower) { var leftBits = left.GetDeepCopy().GetBitsMSB(); var rightBits = right.GetDeepCopy().GetBitsMSB(); var resultBits = new bool[moduloPower]; var carryOver = false; for (var i = moduloPower - 1; i >= 0; i--) { // Lack of implicit conversion here is gross var bitResult = Convert.ToInt32(leftBits[i]) + Convert.ToInt32(rightBits[i]) + Convert.ToInt32(carryOver); carryOver = (bitResult >= 2); resultBits[i] = (bitResult % 2 == 1); } Array.Reverse(resultBits); return(new BitString(new BitArray(resultBits))); }
public static BitString NOT(BitString source) { BitString val = source.GetDeepCopy(); return(new BitString(val.Bits.Not())); }