/* private static double GetMantissa10(Radix100 r) { double val = (double)r; double logValue = Math.Log(Math.Abs(val), 10); long exponent = (long)Math.Floor(logValue); double divisor = Math.Pow(10, exponent); double mantissa = val / divisor; return mantissa; } */ private static sbyte GetExponent(Radix100 r) { byte expByte = (byte)((r.val & exponentMask) >> exponentShift); return (sbyte)(expByte - 0x40); }
private static ulong GetMantissa100(Radix100 r) { return (r.val & MantissaMask); }
public static int Sign(Radix100 r) { if (r.Equals(Radix100.Zero)) return 0; if (r.val > 0x8000000000000000) return -1; return 1; }
public static double ToDouble(Radix100 r) { int expValue = GetExponent(r); double val = 0; double powerValue = Math.Pow(100, expValue); for (int i = 6; i >= 0; i--) { ulong digit = (r.val & digitMasks[i]) >> (i * 8); if (digit != 0) val = val + digit * powerValue; powerValue /= 100; } return val * Radix100.Sign(r); }
public static Radix100 Round(Radix100 r, int numOfDecimalDigits) { // We need to find the byte that controls rounding. This depends // on the input - numOfDecimalDigits, and also on the number of // decimal digits in the most significant Radix100 digit of r. int numOfDigitsInMsd = GetByte(r.val, 6) > 10 ? 2 : 1; // This "normalizes" the digit we are looking for, If the most // significant Radix100 digit of r had only 1 decimal digit, then it // is like we are looking for the digit numOfDecimalDigits + 1. (This // accounts for the leading 0 digit in the MSD). numOfDecimalDigits = numOfDecimalDigits + (2 - numOfDigitsInMsd); // The digit that controls rounding is in the byte we grab here: byte bytePos = (byte) (7 - (numOfDecimalDigits + 2) / 2); byte byteOfConcern = GetByte(r.val, bytePos); // Now the digit that controls rounding is either in the 10s position // or 1s position of the byte we just grabbed. bool onesPosition = (numOfDecimalDigits % 2) != 0; byte digitOfConcern =(byte) (onesPosition ? (byteOfConcern % 10) : (byteOfConcern / 10)); Radix100 roundUpVal = Radix100.Zero; if (digitOfConcern >= 5) { // Create a Radix100 that can be added to the truncted value // we create below to get the rounded value. ulong newVal = 0; SetByte(ref newVal, 7, GetByte(r.val, 7)); // If our rounding digit was in onesPosition, then we need to put a // 1 in the tens position. Else put a 1 in the ones position of next higher byte. if (onesPosition) SetByte(ref newVal, bytePos, 10); else SetByte(ref newVal, bytePos + 1, 1); roundUpVal = new Radix100(newVal); } // the last decimal digit is in the byte we are going to grab: bytePos = (byte)(7 - (numOfDecimalDigits + 1) / 2); byteOfConcern = GetByte(r.val, bytePos); onesPosition = (numOfDecimalDigits % 2) == 0; digitOfConcern = (byte)(onesPosition ? (byteOfConcern % 10) : (byteOfConcern / 10)); ulong truncatedValue = 0; for (int i = 7; i > bytePos; i--) { SetByte(ref truncatedValue, i, GetByte(r.val, i)); } if (onesPosition) SetByte(ref truncatedValue, bytePos, GetByte(r.val, bytePos)); else SetByte(ref truncatedValue, bytePos, (byte)(digitOfConcern*10)); Radix100 result = new Radix100(truncatedValue); return result + roundUpVal; }
public static Radix100 Negate(Radix100 r) { ulong val = r.val ^ 0x8000000000000000; return new Radix100(val); }
public static Radix100 Log(Radix100 r) { return (Radix100) Math.Log(r); }
public static Radix100 FromDouble(double d) { // Let's retrieve the mantissa, exponent and sign in terms of Radix 100. int sign = Math.Sign(d); sbyte exponent = (sbyte) Math.Floor(Math.Log(Math.Abs(d), 100)); double mantissa = Math.Abs(d / Math.Pow(100, exponent)); ulong result = 0; // set exponent properly byte biasedExponent = BiasedExponentValue(exponent); SetByte(ref result, 7, biasedExponent); byte digit; // loop through digits for (int i = 6; i >= 0 && mantissa > 0; i--) { digit = (byte)Math.Truncate(mantissa); SetByte(ref result, i, digit); mantissa = (mantissa * 100) - (digit * 100); } // Now check the remaining mantissa. If it is >= 50 then we should round up // the last digit. bool roundUp = (mantissa >= 50.0); Radix100 roundUpValue = new Radix100(0); if (roundUp) { // Create a Radix100 with same exponent with a 1 in the least significant // digit of the mantissa. This can then be added to our result. ulong r = 0; SetByte(ref r, 7, biasedExponent); SetByte(ref r, 0, 1); roundUpValue = new Radix100(r); } Radix100 retVal = new Radix100(result); if (roundUp) retVal = retVal + roundUpValue; if (sign < 0) retVal = Radix100.Negate(retVal); return retVal; }
public static Radix100 Exp(Radix100 r) { double d = Math.Exp(r); Radix100 result = (Radix100)d; return result; }