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];
}