コード例 #1
0
ファイル: CRTBaseMath.cs プロジェクト: Eric7Apps/BlogSource
        internal int SetFromCRTNumber( CRTBase ToSet, ChineseRemainder SetFrom )
        {
            try
            {
            if( NumbersArray == null )
              throw( new Exception( "Bug: The NumbersArray should have been set up already." ));

            // ToSet.SetToZero();

            // CRTBaseArray[0] is 1.
            if( SetFrom.GetDigitAt( 0 ) == 1 )
              {
              ToSet.SetToOne(); // 1 times 1 for this base.
              CRTAccumulateForBaseMultiples.SetToOne();
              }
            else
              {
              ToSet.SetToZero();
              CRTAccumulateForBaseMultiples.SetToZero();
              }

            int HighestNonZeroDigit = 1;
            // Count starts at 1, so it's at the prime 3.
            for( int Count = 1; Count < ChineseRemainder.DigitsArraySize; Count++ )
              {
              int Prime = (int)IntMath.GetPrimeAt( Count );
              int AccumulateDigit = CRTAccumulateForBaseMultiples.GetDigitAt( Count );
              int CRTInputTestDigit = SetFrom.GetDigitAt( Count );
              int BaseDigit = CRTBaseArray[Count].GetDigitAt( Count );
              if( BaseDigit == 0 )
            throw( new Exception( "This never happens. BaseDigit == 0." ));

              int BaseMult = CRTInputTestDigit;
              if( BaseMult < AccumulateDigit )
            BaseMult += Prime;

              BaseMult -= AccumulateDigit;
              int Inverse = MultInverseArray[Count, BaseDigit];
              BaseMult = (BaseMult * Inverse) % Prime;

              ToSet.SetDigitAt( BaseMult, Count );
              if( BaseMult != 0 )
            HighestNonZeroDigit = Count;

              // Notice that this is using CRTBaseArray and not
              // CRTBaseModArray.
              // This would be very fast in parallel hardware,
              // but not in software that has to do each digit
              // one at a time.
              CRTAccumulatePart.Copy( CRTBaseArray[Count] );
              CRTAccumulatePart.Multiply( NumbersArray[BaseMult] );
              CRTAccumulateForBaseMultiples.Add( CRTAccumulatePart );
              }

            return HighestNonZeroDigit;
            }
            catch( Exception Except )
              {
              throw( new Exception( "Exception in SetFromCRTNumber(): " + Except.Message ));
              }
        }