예제 #1
0
        /// <summary>
        /// Returns the index form of the given decimal, assuming that this polynomial is a primitive polynomial for a finite field
        /// </summary>
        /// <param name="decimalForm"></param>
        /// <returns></returns>
        public BigInteger GetIndexForm(BigInteger decimalForm)
        {
            if (decimalForm.IsZero)
            {
                return(0);                // This is by definition
            }
            // This is kind of the opposite of performing modulus. Instead of subtracting increasing smaller multiples of the primitive polynomial to cancel out the higher bits until there's only a remainder left, we start with the remainder and add on increasingly larger multiples of the primitive polynomial in order to cancel out the lower bits until only a single bit is set
            var binary     = new BinaryNumber(decimalForm);         // The binary version of the given decimal
            var polynomial = new BinaryNumber(GetNumber());         // The binary version of this polynomial. Note that BinaryNumber's bits are set from most- to least-significant, which is the opposite of a Polynomial

            // Define a method that will throw an exception if things don't work
            var throwException = new Action(() =>
            {
                throw new Exception("This number doesn't work as a primitive polynomial for the given number, because a power of the generator couldn't be found");
            });

            // Figure out the maximum number of shifts that we'll allow before giving up
            var maxShifts = BigInteger.Pow(2, polynomial.Count - 1);      // We'll look for up to this power of the generator

            var shifts = new BigInteger();                                // Keeps track of the number of shifts that have been made

            while (binary.Count > 1)                                      // Keep looping as long as there is more than one bit left to cancel out
            {
                binary ^= polynomial;                                     // XOR with the polynomial. This gets rid of successively more lower bits
                while (!binary.LeastSignificantBit() && binary.Count > 1) // Shift right to get rid of trailing zeros
                {
                    binary.RotateRight();
                    shifts++;                     // Keep track of the number of shifts that were made
                }
                if (shifts > maxShifts)
                {
                    throwException();
                }
            }

            if (binary.First.Value)             // We wound up with the number "1" by itself. This means that the index is x^shifts
            {
                return(shifts);
            }
            else             // We wound up with zero. This means that the index form of the given decimal is undefined
            {
                throwException();
            }

            // Code shouldn't get this far, but the compiler doesn't recognize that our exception method will always throw an exception
            throw new NotImplementedException();
        }