System.Xml.Xsl.XPathConvert.BigNumber.MulTenAdd C# (CSharp) Method

MulTenAdd() private method

private MulTenAdd ( uint digit ) : uint
digit uint
return uint
            private unsafe uint MulTenAdd(uint digit) {
                Debug.Assert(digit <= 9);
                Debug.Assert(0 != (this.u2 & 0x80000000));

                // First "multipy" by eight
                this.exp += 3;
                Debug.Assert(this.exp >= 4);

                // Initialize the carry values based on digit and exp.
                uint *rgu = stackalloc uint[5];
                for (int i = 0; i < 5; i++) {
                    rgu[i] = 0;
                }
                if (0 != digit) {
                    int idx = 3 - (this.exp >> 5);
                    if (idx < 0) {
                        rgu[0] = 1;
                    } else {
                        int ibit = this.exp & 0x1F;
                        if (ibit < 4) {
                            rgu[idx + 1] = digit >> ibit;
                            if (ibit > 0) {
                                rgu[idx] = digit << (32 - ibit);
                            }
                        } else {
                            rgu[idx] = digit << (32 - ibit);
                        }
                    }
                }

                // Shift and add to multiply by ten.
                rgu[1] += AddU(ref rgu[0], this.u0 << 30);
                rgu[2] += AddU(ref this.u0, (this.u0 >> 2) + (this.u1 << 30));
                if (0 != rgu[1]) {
                    rgu[2] += AddU(ref this.u0, rgu[1]);
                }
                rgu[3] += AddU(ref this.u1, (this.u1 >> 2) + (this.u2 << 30));
                if (0 != rgu[2]) {
                    rgu[3] += AddU(ref this.u1, rgu[2]);
                }
                rgu[4] = AddU(ref this.u2, (this.u2 >> 2) + rgu[3]);

                // Handle the final carry.
                if (0 != rgu[4]) {
                    Debug.Assert(1 == rgu[4]);
                    rgu[0] = (rgu[0] >> 1) | (rgu[0] & 1) | (this.u0 << 31);
                    this.u0 = (this.u0 >> 1) | (this.u1 << 31);
                    this.u1 = (this.u1 >> 1) | (this.u2 << 31);
                    this.u2 = (this.u2 >> 1) | 0x80000000;
                    this.exp++;
                }

                return rgu[0];
            }