Beispiel #1
0
 public ArithmeticCalculator(IAdder <T> adder, ISubtractor <T> subtractor, IMultiplier <T> multiplier, IDivider <T> divider)
 {
     _adder      = adder;
     _subtractor = subtractor;
     _multiplier = multiplier;
     _divider    = divider;
 }
Beispiel #2
0
 public Calculator(IQueryParser queryParser, IMultiplier multipler, IAdder adder, ISubtractor subtractor, IDivider divider)
 {
     _queryParser = queryParser;
     _multiplier  = multipler;
     _adder       = adder;
     _subtractor  = subtractor;
     _divider     = divider;
 }
Beispiel #3
0
 public Calculator(IAdder adder, ISubtractor subtractor, IDivider divider, IMultiplier multiplier, IExponenter exponenter)
 {
     this.adder      = adder;
     this.subtractor = subtractor;
     this.divider    = divider;
     this.multiplier = multiplier;
     this.exponenter = exponenter;
 }
 public Application(
     IMultiplier multiplier,
     IMultiplicationResultFormatter formatter
     )
 {
     this.multiplier = multiplier;
     this.formatter  = formatter;
 }
 public ApplicationFacade(IMultiplier multiplier, IEnumerable <IOutputFormatter> formatters)
 {
     _multiplier = multiplier;
     foreach (IOutputFormatter outputFormatter in formatters)
     {
         _formattersDictionary.Add(outputFormatter.Format, outputFormatter);
     }
 }
Beispiel #6
0
        // .cctor
        static MultiplyManager()
        {
            // Create new classic multiplier instance
            IMultiplier classicMultiplier = new ClassicMultiplier();

            // Fill publicity visible multiplier fields
            ClassicMultiplier = classicMultiplier;
            AutoFhtMultiplier = new AutoFhtMultiplier(classicMultiplier);
        }
Beispiel #7
0
        // .cctor
        static MultiplyManager()
        {
            // Create new classic multiplier instance
            IMultiplier classicMultiplier = new ClassicMultiplier();

            // Fill publicity visible multiplier fields
            ClassicMultiplier = classicMultiplier;
            AutoFhtMultiplier = new AutoFhtMultiplier(classicMultiplier);
        }
Beispiel #8
0
 public void CollectGrowable(GrowableIncarnation growable)
 {
     if (growable.CanCollect())
     {
         IMultiplier multiplier = rules.ActiveFinalMultiplierForIdentifiable(growable.Entity);
         BigInteger  amount     = multiplier.Apply(growable.Entity.GrownResource.Amount);
         state.AddResource(growable.Entity.GrownResource.Resource.Entity, amount);
         growable.Reset();
     }
 }
Beispiel #9
0
        /// <summary>
        /// Returns a specified big integer raised to the specified power.
        /// </summary>
        /// <param name="value">Number to raise.</param>
        /// <param name="power">Power.</param>
        /// <param name="multiplyMode">Multiply mode set explicitly.</param>
        /// <returns>Number in given power.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="value" /> is a null reference.</exception>
        static public IntX Pow(IntX value, uint power, MultiplyMode multiplyMode)
        {
            // Exception
            if (ReferenceEquals(value, null))
            {
                throw new ArgumentNullException("value");
            }

            // Return one for zero pow
            if (power == 0)
            {
                return(1);
            }

            // Return the number itself from a power of one
            if (power == 1)
            {
                return(new IntX(value));
            }

            // Return zero for a zero
            if (value._length == 0)
            {
                return(new IntX());
            }

            // Get first one bit
            int msb = Bits.Msb(power);

            // Get multiplier
            IMultiplier multiplier = MultiplyManager.GetMultiplier(multiplyMode);

            // Do actual raising
            IntX res = value;

            for (uint powerMask = 1U << (msb - 1); powerMask != 0; powerMask >>= 1)
            {
                // Always square
                res = multiplier.Multiply(res, res);

                // Maybe mul
                if ((power & powerMask) != 0)
                {
                    res = multiplier.Multiply(res, value);
                }
            }
            return(res);
        }
Beispiel #10
0
        public BaseExerciseModel(IExerciseConfiguration config, IExerciseInitVO initVO, ILogger logger)
        {
            _logger = logger;
            ExerciseConfiguration = config;
            ExerciseInitVO        = initVO;
            _exerciseSettings     = initVO.Settings;

            // Init the property changes for tracking
            _propertiesUpdates = new Dictionary <Type, IModelPropertyUpdateVO>();

            _totalGoodRuns       = 0;
            TotalRuns            = 0;
            _currentGoodRuns     = 0;
            _currentBadRuns      = 0;
            GoodRunsInARow       = 0;
            _warmUpRoundsCounter = 1;
            _warmUpEnabeld       = initVO.WarmUpEnabled;

            _startDifficulty = (initVO.StartDifficulty > ExerciseConfiguration.MaxDifficulty) ? ExerciseConfiguration.MaxDifficulty : initVO.StartDifficulty;

#pragma warning disable RECS0021 // Warns about calls to virtual member functions occuring in the constructor
            _multiplier = InitMultiplier(_startDifficulty, ExerciseConfiguration);
#pragma warning restore RECS0021 // Warns about calls to virtual member functions occuring in the constructor
            // listen to multiplier changes
            _multiplier.OnChanged += OnMultiplierChanged;

#pragma warning disable RECS0021 // Warns about calls to virtual member functions occuring in the constructor
            _bonusScore = GetScoreForStartingDifficulty(_startDifficulty);
#pragma warning restore RECS0021 // Warns about calls to virtual member functions occuring in the constructor

            _currentDifficulty = _startDifficulty;

            AddPropertyUpdate(new BadRunsToLevelDownUpdateVO(ExerciseConfiguration.GetBadRunsByLevel(_startDifficulty), ExerciseConfiguration.GetBadRunsByLevel(_startDifficulty)));
            AddPropertyUpdate(new GoodRunsToLevelUpUpdateVO(ExerciseConfiguration.GetGoodRunsByLevel(_startDifficulty), ExerciseConfiguration.GetGoodRunsByLevel(_startDifficulty)));
            AddPropertyUpdate(new DifficultyUpdateVO(_startDifficulty, _startDifficulty));
            AddPropertyUpdate(new MaxDifficultyUpdateVO(ExerciseConfiguration.MaxDifficulty, ExerciseConfiguration.MaxDifficulty));

            _warmUpState = _warmUpEnabeld && (ExerciseConfiguration.GetWarmUpRoundsByLevel(_currentDifficulty) > 0)?WarmUpState.Enabled:WarmUpState.Disabled;

            if (_warmUpState == WarmUpState.Enabled)
            {
                var originalValue = ExerciseConfiguration.GetWarmUpRoundsByLevel(_currentDifficulty);
                AddPropertyUpdate(new WarmUpUpdateVO(originalValue, originalValue, originalValue));
            }

            _lastRoundLevelChange = LevelState.NEW;
        }
Beispiel #11
0
        public IReadOnlyCollection <TestMethodInstance> Explode(IMultiplier testMethodMultiplier)
        {
            var result = new List <TestMethodInstance>();

            // get the class instance
            var classInstance = GetClassInstance(Method.ReflectedType);

            var param = FindParameters(classInstance);
            // do the param fit in the method ?

            var infos = Method.GetParameters();
            IEnumerable <object[]> enumerable = param as IList <object[]> ?? param.ToList();
            var nbParamFromDataProvider       = NbParamFromDataProvider(enumerable);

            if (infos.Count() != nbParamFromDataProvider)
            {
                throw new DataProviderException("expected " + infos.Count() + " parameters but got " + nbParamFromDataProvider);
            }
            return(GetMethodInstance(enumerable, result, classInstance, testMethodMultiplier));
        }
Beispiel #12
0
 /// <summary>
 /// Adds the given element to the collection
 /// </summary>
 /// <param name="item">The item to add</param>
 public override void Add(IModelElement item)
 {
     if ((this._parent.SlUnits == null))
     {
         ISlUnits slUnitsCasted = item.As <ISlUnits>();
         if ((slUnitsCasted != null))
         {
             this._parent.SlUnits = slUnitsCasted;
             return;
         }
     }
     if ((this._parent.Multiplier == null))
     {
         IMultiplier multiplierCasted = item.As <IMultiplier>();
         if ((multiplierCasted != null))
         {
             this._parent.Multiplier = multiplierCasted;
             return;
         }
     }
 }
        public void ExecuteSkill(bool isKeyDown)
        {
            var canCastSkill = Time.time >= _cd;

            if (canCastSkill && _plyJump.IsGrounded)
            {
                if (_isSkillActive && !isKeyDown)
                {
                    _isSkillActive  = false;
                    _rb.constraints = RigidbodyConstraints2D.None | RigidbodyConstraints2D.FreezeRotation;
                    _anim.SetTrigger("Shoot");

                    var projectilePrefab = TrySpawnProjectile();

                    float chargeTimePassedHalved = (Time.time - _startChargeTime) / 2 + 0.25f;
                    float chargedAmount          = chargeTimePassedHalved * ChargeRate;
                    float charged = chargedAmount < 10 ? chargedAmount : 10;

                    if (projectilePrefab)
                    {
                        projectilePrefab.transform.localScale = new Vector3(charged, charged, charged);

                        IMultiplier multiplier = projectilePrefab.GetComponent <IMultiplier>();
                        multiplier.SetMultiplier(charged * 3);
                    }


                    _cd = Time.time + Cooldown;
                }
                else if (!_isSkillActive && isKeyDown)
                {
                    _isSkillActive  = true;
                    _rb.constraints = RigidbodyConstraints2D.FreezeAll;
                    _anim.SetTrigger("StartCharge");
                    _startChargeTime = Time.time;
                }
            }
        }
Beispiel #14
0
 public WebTestMethodExploder(MethodInfo method, Configuration config) : base(method)
 {
     _multiplier = new WebTestMultiplier(config);
 }
 public MultiplicationController(IMultiplier multiplier)
 {
     _multiplier = multiplier;
 }
Beispiel #16
0
 public MultiplyController(ILogger <MultiplyController> logger, IMultiplier multiplier)
 {
     _logger     = logger;
     _multiplier = multiplier;
 }
 public BeforeSuiteWebTestMethodExploder(MethodInfo method, Configuration config) : base(method)
 {
     _beforeSuiteWebTestMethodMultiplier = new BeforeSuiteWebTestMethodMultiplier(config);
 }
 public AfterSuiteWebTestMethodExploder(MethodInfo method, Configuration config)
     : base(method)
 {
     _afterSuiteWebTestMethodMultiplier = new AfterSuiteWebTestMethodMultiplier(config);
 }
Beispiel #19
0
        /// <summary>
        /// Converts digits from internal representaion into given base.
        /// </summary>
        /// <param name="digits">Big integer digits.</param>
        /// <param name="length">Big integer length.</param>
        /// <param name="numberBase">Base to use for output.</param>
        /// <param name="outputLength">Calculated output length (will be corrected inside).</param>
        /// <returns>Conversion result (later will be transformed to string).</returns>
        override unsafe public uint[] ToString(uint[] digits, uint length, uint numberBase, ref uint outputLength)
        {
            uint[] outputArray = base.ToString(digits, length, numberBase, ref outputLength);

            // Maybe base method already converted this number
            if (outputArray != null)
            {
                return(outputArray);
            }

            // Check length - maybe use classic converter instead
            if (length < Constants.FastConvertLengthLowerBound || length > Constants.FastConvertLengthUpperBound)
            {
                return(_classicStringConverter.ToString(digits, length, numberBase, ref outputLength));
            }

            int  resultLengthLog2 = Bits.CeilLog2(outputLength);
            uint resultLength     = 1U << resultLengthLog2;

            // Create and initially fill array for transofmed numbers storing
            uint[] resultArray = ArrayPool <uint> .Instance.GetArray(resultLength);

            Array.Copy(digits, resultArray, length);

            // Create and initially fill array with lengths
            uint[] resultArray2 = ArrayPool <uint> .Instance.GetArray(resultLength);

            resultArray2[0] = length;

            IMultiplier multiplier = MultiplyManager.GetCurrentMultiplier();
            IDivider    divider    = DivideManager.GetCurrentDivider();

            // Generate all needed pows of numberBase in stack
            Stack baseIntStack = new Stack(resultLengthLog2);
            IntX  baseInt      = null;

            for (int i = 0; i < resultLengthLog2; ++i)
            {
                baseInt = baseInt == null ? numberBase : multiplier.Multiply(baseInt, baseInt);
                baseIntStack.Push(baseInt);
            }

            // Create temporary buffer for second digits when doing div operation
            uint[] tempBuffer = new uint[baseInt._length];

            // We will use unsafe code here
            fixed(uint *resultPtr1Const = resultArray, resultPtr2Const = resultArray2, tempBufferPtr = tempBuffer)
            {
                // Results pointers which will be modified (on swap)
                uint *resultPtr1 = resultPtr1Const;
                uint *resultPtr2 = resultPtr2Const;

                // Temporary variables used on swapping
                uint[] tempArray;
                uint * tempPtr;

                // Variables used in cycle
                uint *ptr1, ptr2, ptr1end;
                uint  loLength;

                // Outer cycle instead of recursion
                for (uint innerStep = resultLength >> 1, outerStep = resultLength; innerStep > 0; innerStep >>= 1, outerStep >>= 1)
                {
                    // Prepare pointers
                    ptr1    = resultPtr1;
                    ptr2    = resultPtr2;
                    ptr1end = resultPtr1 + resultLength;

                    // Get baseInt from stack and fix it too
                    baseInt = (IntX)baseIntStack.Pop();
                    fixed(uint *baseIntPtr = baseInt._digits)
                    {
                        // Cycle thru all digits and their lengths
                        for (; ptr1 < ptr1end; ptr1 += outerStep, ptr2 += outerStep)
                        {
                            // Divide ptr1 (with length in *ptr2) by baseIntPtr here.
                            // Results are stored in ptr2 & (ptr2 + innerStep), lengths - in *ptr1 and (*ptr1 + innerStep)
                            loLength            = *ptr2;
                            *(ptr1 + innerStep) = divider.DivMod(
                                ptr1,
                                ptr2,
                                ref loLength,
                                baseIntPtr,
                                tempBufferPtr,
                                baseInt._length,
                                ptr2 + innerStep,
                                DivModResultFlags.Div | DivModResultFlags.Mod,
                                -2);
                            *ptr1 = loLength;
                        }
                    }

                    // After inner cycle resultArray will contain lengths and resultArray2 will contain actual values
                    // so we need to swap them here
                    tempArray    = resultArray;
                    resultArray  = resultArray2;
                    resultArray2 = tempArray;

                    tempPtr    = resultPtr1;
                    resultPtr1 = resultPtr2;
                    resultPtr2 = tempPtr;
                }

                // Retrieve real output length
                outputLength = DigitHelper.GetRealDigitsLength(resultArray2, outputLength);

                // Create output array
                outputArray = new uint[outputLength];

                // Copy each digit but only if length is not null
                fixed(uint *outputPtr = outputArray)
                {
                    for (uint i = 0; i < outputLength; ++i)
                    {
                        if (resultPtr2[i] != 0)
                        {
                            outputPtr[i] = resultPtr1[i];
                        }
                    }
                }
            }

            // Return temporary arrays to pool
            ArrayPool <uint> .Instance.AddArray(resultArray);

            ArrayPool <uint> .Instance.AddArray(resultArray2);

            return(outputArray);
        }
Beispiel #20
0
 /// <summary>
 /// Creates a new observable property access proxy
 /// </summary>
 /// <param name="modelElement">The model instance element for which to create the property access proxy</param>
 public ValProxy(IMultiplier modelElement) :
     base(modelElement, "val")
 {
 }
		IMultiplier _classicMultiplier; // multiplier to use if FHT is unapplicatible

		#endregion Private fields

		#region Constructor

		/// <summary>
		/// Creates new <see cref="AutoFhtMultiplier" /> instance.
		/// </summary>
		/// <param name="classicMultiplier">Multiplier to use if FHT is unapplicatible.</param>
		public AutoFhtMultiplier(IMultiplier classicMultiplier)
		{
			_classicMultiplier = classicMultiplier;
		}
Beispiel #22
0
        IMultiplier _classicMultiplier;         // multiplier to use if FHT is unapplicatible

        #endregion Private fields

        #region Constructor

        /// <summary>
        /// Creates new <see cref="AutoFhtMultiplier" /> instance.
        /// </summary>
        /// <param name="classicMultiplier">Multiplier to use if FHT is unapplicatible.</param>
        public AutoFhtMultiplier(IMultiplier classicMultiplier)
        {
            _classicMultiplier = classicMultiplier;
        }
Beispiel #23
0
 public CachedMultiplier(IMultiplier multiplier)
 {
     _multiplier = multiplier;
 }
 public SampleMathUtility(IMultiplier multiplier)
 {
     this.Multiplier = multiplier;
 }
Beispiel #25
0
        /// <summary>
        /// Generates integer opposite to the given one using approximation.
        /// Uses algorithm from Khuth vol. 2 3rd Edition (4.3.3).
        /// </summary>
        /// <param name="digitsPtr">Initial big integer digits.</param>
        /// <param name="length">Initial big integer length.</param>
        /// <param name="maxLength">Precision length.</param>
        /// <param name="bufferPtr">Buffer in which shifted big integer may be stored.</param>
        /// <param name="newLength">Resulting big integer length.</param>
        /// <param name="rightShift">How much resulting big integer is shifted to the left (or: must be shifted to the right).</param>
        /// <returns>Resulting big integer digits.</returns>
        static unsafe public uint[] GetIntegerOpposite(
            uint *digitsPtr,
            uint length,
            uint maxLength,
            uint *bufferPtr,
            out uint newLength,
            out ulong rightShift)
        {
            // Maybe initially shift original digits a bit to the left
            // (it must have MSB on 2nd position in the highest digit)
            int msb = Bits.Msb(digitsPtr[length - 1]);

            rightShift = (ulong)(length - 1) * Constants.DigitBitCount + (ulong)msb + 1U;

            if (msb != 2)
            {
                // Shift to the left (via actually right shift)
                int leftShift = (2 - msb + Constants.DigitBitCount) % Constants.DigitBitCount;
                length = DigitOpHelper.Shr(digitsPtr, length, bufferPtr + 1, Constants.DigitBitCount - leftShift, true) + 1U;
            }
            else
            {
                // Simply use the same digits without any shifting
                bufferPtr = digitsPtr;
            }

            // Calculate possible result length
            int  lengthLog2     = Bits.CeilLog2(maxLength);
            uint newLengthMax   = 1U << (lengthLog2 + 1);
            int  lengthLog2Bits = lengthLog2 + Bits.Msb(Constants.DigitBitCount);

            // Create result digits
            uint[] resultDigits = ArrayPool <uint> .Instance.GetArray(newLengthMax);           //new uint[newLengthMax];

            uint resultLength;

            // Create temporary digits for squared result (twice more size)
            uint[] resultDigitsSqr = ArrayPool <uint> .Instance.GetArray(newLengthMax);           //new uint[newLengthMax];

            uint resultLengthSqr;

            // Create temporary digits for squared result * buffer
            uint[] resultDigitsSqrBuf = new uint[newLengthMax + length];
            uint   resultLengthSqrBuf;

            // We will always use current multiplier
            IMultiplier multiplier = MultiplyManager.GetCurrentMultiplier();

            // Fix some digits
            fixed(uint *resultPtrFixed = resultDigits, resultSqrPtrFixed = resultDigitsSqr, resultSqrBufPtr = resultDigitsSqrBuf)
            {
                uint *resultPtr    = resultPtrFixed;
                uint *resultSqrPtr = resultSqrPtrFixed;

                // Cache two first digits
                uint bufferDigitN1 = bufferPtr[length - 1];
                uint bufferDigitN2 = bufferPtr[length - 2];

                // Prepare result.
                // Initially result = floor(32 / (4*v1 + 2*v2 + v3)) / 4
                // (last division is not floored - here we emulate fixed point)
                resultDigits[0] = 32 / bufferDigitN1;
                resultLength    = 1;

                // Prepare variables
                uint  nextBufferTempStorage = 0;
                int   nextBufferTempShift;
                uint  nextBufferLength = 1U;
                uint *nextBufferPtr    = &nextBufferTempStorage;

                ulong bitsAfterDotResult;
                ulong bitsAfterDotResultSqr;
                ulong bitsAfterDotNextBuffer;
                ulong bitShift;
                uint  shiftOffset;

                uint *tempPtr;

                uint[] tempDigits;

                // Iterate 'till result will be precise enough
                for (int k = 0; k < lengthLog2Bits; ++k)
                {
                    // Get result squared
                    resultLengthSqr = multiplier.Multiply(
                        resultPtr,
                        resultLength,
                        resultPtr,
                        resultLength,
                        resultSqrPtr);

                    // Calculate current result bits after dot
                    bitsAfterDotResult    = (1UL << k) + 1UL;
                    bitsAfterDotResultSqr = bitsAfterDotResult << 1;

                    // Here we will get the next portion of data from bufferPtr
                    if (k < 4)
                    {
                        // For now buffer intermediate has length 1 and we will use this fact
                        nextBufferTempShift   = 1 << (k + 1);
                        nextBufferTempStorage =
                            bufferDigitN1 << nextBufferTempShift |
                                bufferDigitN2 >> (Constants.DigitBitCount - nextBufferTempShift);

                        // Calculate amount of bits after dot (simple formula here)
                        bitsAfterDotNextBuffer = (ulong)nextBufferTempShift + 3UL;
                    }
                    else
                    {
                        // Determine length to get from bufferPtr
                        nextBufferLength = System.Math.Min((1U << (k - 4)) + 1U, length);
                        nextBufferPtr    = bufferPtr + (length - nextBufferLength);

                        // Calculate amount of bits after dot (simple formula here)
                        bitsAfterDotNextBuffer = (ulong)(nextBufferLength - 1U) * Constants.DigitBitCount + 3UL;
                    }

                    // Multiply result ^ 2 and nextBuffer + calculate new amount of bits after dot
                    resultLengthSqrBuf = multiplier.Multiply(
                        resultSqrPtr,
                        resultLengthSqr,
                        nextBufferPtr,
                        nextBufferLength,
                        resultSqrBufPtr);

                    bitsAfterDotNextBuffer += bitsAfterDotResultSqr;

                    // Now calculate 2 * result - resultSqrBufPtr
                    --bitsAfterDotResult;
                    --bitsAfterDotResultSqr;

                    // Shift result on a needed amount of bits to the left
                    bitShift     = bitsAfterDotResultSqr - bitsAfterDotResult;
                    shiftOffset  = (uint)(bitShift / Constants.DigitBitCount);
                    resultLength =
                        shiftOffset + 1U +
                        DigitOpHelper.Shr(
                            resultPtr,
                            resultLength,
                            resultSqrPtr + shiftOffset + 1U,
                            Constants.DigitBitCount - (int)(bitShift % Constants.DigitBitCount),
                            true);

                    // Swap resultPtr and resultSqrPtr pointers
                    tempPtr      = resultPtr;
                    resultPtr    = resultSqrPtr;
                    resultSqrPtr = tempPtr;

                    tempDigits      = resultDigits;
                    resultDigits    = resultDigitsSqr;
                    resultDigitsSqr = tempDigits;

                    DigitHelper.SetBlockDigits(resultPtr, shiftOffset, 0U);

                    bitShift    = bitsAfterDotNextBuffer - bitsAfterDotResultSqr;
                    shiftOffset = (uint)(bitShift / Constants.DigitBitCount);

                    if (shiftOffset < resultLengthSqrBuf)
                    {
                        // Shift resultSqrBufPtr on a needed amount of bits to the right
                        resultLengthSqrBuf = DigitOpHelper.Shr(
                            resultSqrBufPtr + shiftOffset,
                            resultLengthSqrBuf - shiftOffset,
                            resultSqrBufPtr,
                            (int)(bitShift % Constants.DigitBitCount),
                            false);

                        // Now perform actual subtraction
                        resultLength = DigitOpHelper.Sub(
                            resultPtr,
                            resultLength,
                            resultSqrBufPtr,
                            resultLengthSqrBuf,
                            resultPtr);
                    }
                    else
                    {
                        // Actually we can assume resultSqrBufPtr == 0 here and have nothing to do
                    }
                }
            }

            // Return some arrays to pool
            ArrayPool <uint> .Instance.AddArray(resultDigitsSqr);

            rightShift += (1UL << lengthLog2Bits) + 1UL;
            newLength   = resultLength;
            return(resultDigits);
        }
Beispiel #26
0
        /// <summary>
        /// Parses provided string representation of <see cref="IntX" /> object.
        /// </summary>
        /// <param name="value">Number as string.</param>
        /// <param name="startIndex">Index inside string from which to start.</param>
        /// <param name="endIndex">Index inside string on which to end.</param>
        /// <param name="numberBase">Number base.</param>
        /// <param name="charToDigits">Char->digit dictionary.</param>
        /// <param name="digitsRes">Resulting digits.</param>
        /// <returns>Parsed integer length.</returns>
        override unsafe public uint Parse(string value, int startIndex, int endIndex, uint numberBase, IDictionary <char, uint> charToDigits, uint[] digitsRes)
        {
            uint newLength = base.Parse(value, startIndex, endIndex, numberBase, charToDigits, digitsRes);

            // Maybe base method already parsed this number
            if (newLength != 0)
            {
                return(newLength);
            }

            // Check length - maybe use classic parser instead
            uint initialLength = (uint)digitsRes.LongLength;

            if (initialLength < Constants.FastParseLengthLowerBound || initialLength > Constants.FastParseLengthUpperBound)
            {
                return(_classicParser.Parse(value, startIndex, endIndex, numberBase, charToDigits, digitsRes));
            }

            uint valueLength  = (uint)(endIndex - startIndex + 1);
            uint digitsLength = 1U << Bits.CeilLog2(valueLength);

            // Prepare array for digits in other base
            uint[] valueDigits = ArrayPool <uint> .Instance.GetArray(digitsLength);

            // This second array will store integer lengths initially
            uint[] valueDigits2 = ArrayPool <uint> .Instance.GetArray(digitsLength);

            fixed(uint *valueDigitsStartPtr = valueDigits, valueDigitsStartPtr2 = valueDigits2)
            {
                // In the string first digit means last in digits array
                uint *valueDigitsPtr  = valueDigitsStartPtr + valueLength - 1;
                uint *valueDigitsPtr2 = valueDigitsStartPtr2 + valueLength - 1;

                // Reverse copy characters into digits
                fixed(char *valueStartPtr = value)
                {
                    char *valuePtr    = valueStartPtr + startIndex;
                    char *valueEndPtr = valuePtr + valueLength;

                    for (; valuePtr < valueEndPtr; ++valuePtr, --valueDigitsPtr, --valueDigitsPtr2)
                    {
                        // Get digit itself - this call will throw an exception if char is invalid
                        *valueDigitsPtr = StrRepHelper.GetDigit(charToDigits, *valuePtr, numberBase);

                        // Set length of this digit (zero for zero)
                        *valueDigitsPtr2 = *valueDigitsPtr == 0U ? 0U : 1U;
                    }
                }

                // We have retrieved lengths array from pool - it needs to be cleared before using
                DigitHelper.SetBlockDigits(valueDigitsStartPtr2 + valueLength, digitsLength - valueLength, 0);

                // Now start from the digit arrays beginning
                valueDigitsPtr  = valueDigitsStartPtr;
                valueDigitsPtr2 = valueDigitsStartPtr2;

                // Current multiplier (classic or fast) will be used
                IMultiplier multiplier = MultiplyManager.GetCurrentMultiplier();

                // Here base in needed power will be stored
                IntX baseInt = null;

                // Temporary variables used on swapping
                uint[] tempDigits;
                uint * tempPtr;

                // Variables used in cycle
                uint *ptr1, ptr2, valueDigitsPtrEnd;
                uint  loLength, hiLength;

                // Outer cycle instead of recursion
                for (uint innerStep = 1, outerStep = 2; innerStep < digitsLength; innerStep <<= 1, outerStep <<= 1)
                {
                    // Maybe baseInt must be multiplied by itself
                    baseInt = baseInt == null ? numberBase : baseInt * baseInt;

                    // Using unsafe here
                    fixed(uint *baseDigitsPtr = baseInt._digits)
                    {
                        // Start from arrays beginning
                        ptr1 = valueDigitsPtr;
                        ptr2 = valueDigitsPtr2;

                        // vauleDigits array end
                        valueDigitsPtrEnd = valueDigitsPtr + digitsLength;

                        // Cycle thru all digits and their lengths
                        for (; ptr1 < valueDigitsPtrEnd; ptr1 += outerStep, ptr2 += outerStep)
                        {
                            // Get lengths of "lower" and "higher" value parts
                            loLength = *ptr2;
                            hiLength = *(ptr2 + innerStep);

                            if (hiLength != 0)
                            {
                                // We always must clear an array before multiply
                                DigitHelper.SetBlockDigits(ptr2, outerStep, 0U);

                                // Multiply per baseInt
                                hiLength = multiplier.Multiply(
                                    baseDigitsPtr,
                                    baseInt._length,
                                    ptr1 + innerStep,
                                    hiLength,
                                    ptr2);
                            }

                            // Sum results
                            if (hiLength != 0 || loLength != 0)
                            {
                                *ptr1 = DigitOpHelper.Add(
                                    ptr2,
                                    hiLength,
                                    ptr1,
                                    loLength,
                                    ptr2);
                            }
                            else
                            {
                                *ptr1 = 0U;
                            }
                        }
                    }

                    // After inner cycle valueDigits will contain lengths and valueDigits2 will contain actual values
                    // so we need to swap them here
                    tempDigits   = valueDigits;
                    valueDigits  = valueDigits2;
                    valueDigits2 = tempDigits;

                    tempPtr         = valueDigitsPtr;
                    valueDigitsPtr  = valueDigitsPtr2;
                    valueDigitsPtr2 = tempPtr;
                }
            }

            // Determine real length of converted number
            uint realLength = valueDigits2[0];

            // Copy to result
            Array.Copy(valueDigits, digitsRes, realLength);

            // Return arrays to pool
            ArrayPool <uint> .Instance.AddArray(valueDigits);

            ArrayPool <uint> .Instance.AddArray(valueDigits2);

            return(realLength);
        }
Beispiel #27
0
        /// <summary>
        /// Divides two big integers.
        /// Also modifies <paramref name="digitsPtr1" /> and <paramref name="length1"/> (it will contain remainder).
        /// </summary>
        /// <param name="digitsPtr1">First big integer digits.</param>
        /// <param name="digitsBufferPtr1">Buffer for first big integer digits. May also contain remainder.</param>
        /// <param name="length1">First big integer length.</param>
        /// <param name="digitsPtr2">Second big integer digits.</param>
        /// <param name="digitsBufferPtr2">Buffer for second big integer digits. Only temporarily used.</param>
        /// <param name="length2">Second big integer length.</param>
        /// <param name="digitsResPtr">Resulting big integer digits.</param>
        /// <param name="resultFlags">Which operation results to return.</param>
        /// <param name="cmpResult">Big integers comparsion result (pass -2 if omitted).</param>
        /// <returns>Resulting big integer length.</returns>
        override unsafe public uint DivMod(
            uint *digitsPtr1,
            uint *digitsBufferPtr1,
            ref uint length1,
            uint *digitsPtr2,
            uint *digitsBufferPtr2,
            uint length2,
            uint *digitsResPtr,
            DivModResultFlags resultFlags,
            int cmpResult)
        {
            // Maybe immediately use classic algorithm here
            if (IsClassicAlgorithmNeeded(length1, length2))
            {
                return(_classicDivider.DivMod(
                           digitsPtr1,
                           digitsBufferPtr1,
                           ref length1,
                           digitsPtr2,
                           digitsBufferPtr2,
                           length2,
                           digitsResPtr,
                           resultFlags,
                           cmpResult));
            }

            // Call base (for special cases)
            uint resultLength = base.DivMod(
                digitsPtr1,
                digitsBufferPtr1,
                ref length1,
                digitsPtr2,
                digitsBufferPtr2,
                length2,
                digitsResPtr,
                resultFlags,
                cmpResult);

            if (resultLength != uint.MaxValue)
            {
                return(resultLength);
            }


            // First retrieve opposite for the divider
            uint  int2OppositeLength;
            ulong int2OppositeRightShift;

            uint[] int2OppositeDigits = NewtonHelper.GetIntegerOpposite(
                digitsPtr2,
                length2,
                length1,
                digitsBufferPtr1,
                out int2OppositeLength,
                out int2OppositeRightShift);

            // We will need to muptiply it by divident now to receive quotient.
            // Prepare digits for multiply result
            uint quotLength;

            uint[] quotDigits = new uint[length1 + int2OppositeLength];

            IMultiplier multiplier = MultiplyManager.GetCurrentMultiplier();

            // Fix some arrays
            fixed(uint *oppositePtr = int2OppositeDigits, quotPtr = quotDigits)
            {
                // Multiply
                quotLength = multiplier.Multiply(
                    oppositePtr,
                    int2OppositeLength,
                    digitsPtr1,
                    length1,
                    quotPtr);

                // Calculate shift
                uint shiftOffset = (uint)(int2OppositeRightShift / Constants.DigitBitCount);
                int  shiftCount  = (int)(int2OppositeRightShift % Constants.DigitBitCount);

                // Get the very first bit of the shifted part
                uint highestLostBit;

                if (shiftCount == 0)
                {
                    highestLostBit = quotPtr[shiftOffset - 1] >> 31;
                }
                else
                {
                    highestLostBit = quotPtr[shiftOffset] >> (shiftCount - 1) & 1U;
                }

                // After this result must be shifted to the right - this is required
                quotLength = DigitOpHelper.Shr(
                    quotPtr + shiftOffset,
                    quotLength - shiftOffset,
                    quotPtr,
                    shiftCount,
                    false);

                // Maybe quotient must be corrected
                if (highestLostBit == 1U)
                {
                    quotLength = DigitOpHelper.Add(quotPtr, quotLength, &highestLostBit, 1U, quotPtr);
                }

                // Check quotient - finally it might be too big.
                // For this we must multiply quotient by divider
                uint quotDivLength;

                uint[] quotDivDigits = new uint[quotLength + length2];
                fixed(uint *quotDivPtr = quotDivDigits)
                {
                    quotDivLength = multiplier.Multiply(quotPtr, quotLength, digitsPtr2, length2, quotDivPtr);

                    int cmpRes = DigitOpHelper.Cmp(quotDivPtr, quotDivLength, digitsPtr1, length1);

                    if (cmpRes > 0)
                    {
                        highestLostBit = 1;
                        quotLength     = DigitOpHelper.Sub(quotPtr, quotLength, &highestLostBit, 1U, quotPtr);
                        quotDivLength  = DigitOpHelper.Sub(quotDivPtr, quotDivLength, digitsPtr2, length2, quotDivPtr);
                    }

                    // Now everything is ready and prepared to return results

                    // First maybe fill remainder
                    if ((resultFlags & DivModResultFlags.Mod) != 0)
                    {
                        length1 = DigitOpHelper.Sub(digitsPtr1, length1, quotDivPtr, quotDivLength, digitsBufferPtr1);
                    }

                    // And finally fill quotient
                    if ((resultFlags & DivModResultFlags.Div) != 0)
                    {
                        DigitHelper.DigitsBlockCopy(quotPtr, digitsResPtr, quotLength);
                    }
                    else
                    {
                        quotLength = 0;
                    }

                    // Return some arrays to pool
                    ArrayPool <uint> .Instance.AddArray(int2OppositeDigits);

                    return(quotLength);
                }
            }
        }
Beispiel #28
0
 private List <TestMethodInstance> GetMethodInstance(IEnumerable <object[]> param, List <TestMethodInstance> result, object classInstance, IMultiplier methodMultiplier)
 {
     foreach (var parametersValue in param)
     {
         // TODO : move everything to a multiplier construct, ie InvocationCount * whatever else. ?
         // for each invoc count
         for (var i = 0; i < Attribute.InvocationCount; i++)
         {
             // multiply the tests if needed, for instance if multiple browers are needed
             var res = methodMultiplier.Multiply(Method);
             if (res.Count == 0)
             {
                 var metadata = new Dictionary <string, object>();
                 result.Add(new TestMethodInstance(Attribute, metadata, parametersValue, classInstance, Method));
             }
             else
             {
                 foreach (var o in res)
                 {
                     var metadata = new Dictionary <string, object>();
                     metadata[methodMultiplier.Key()] = o;
                     result.Add(new TestMethodInstance(Attribute, metadata, parametersValue, classInstance, Method));
                 }
             }
         }
     }
     return(result);
 }