C# BigDecimal上的内存有效余数函数

C# BigDecimal上的内存有效余数函数,c#,biginteger,bigdecimal,bignum,arbitrary-precision,C#,Biginteger,Bigdecimal,Bignum,Arbitrary Precision,背景: 不久前,我开始为空闲/增量游戏制作自己的BigDecimal实现,它不太关心精度,只关心范围。该类型基于BigInteger 它与其他BigDecimal实现类似。 得到尾数(BigInteger)和指数(int) 我已经实现了所有的基本操作和一些其他数学函数,以备需要。 问题是余数函数。 为了使函数返回正确的结果,我必须使用除法、乘法和减法的全精度,这意味着我必须将分子乘以10^指数(加零以获得精确的除法)问题是,当计算这样一个数字时,速度会很慢,而且最重要的是会影响内存,这对于依赖客

背景: 不久前,我开始为空闲/增量游戏制作自己的BigDecimal实现,它不太关心精度,只关心范围。该类型基于BigInteger

它与其他BigDecimal实现类似。 得到尾数(BigInteger)和指数(int)

我已经实现了所有的基本操作和一些其他数学函数,以备需要。 问题是余数函数。 为了使函数返回正确的结果,我必须使用除法、乘法和减法的全精度,这意味着我必须将分子乘以10^指数(加零以获得精确的除法)问题是,当计算这样一个数字时,速度会很慢,而且最重要的是会影响内存,这对于依赖客户端机器的游戏来说是很好的,但问题是我正在为一个在线游戏制作它,服务器可以有1-2GB内存和许多并发玩家

我已经检查过我是否在游戏中使用过余数函数,没有,我从来没有使用过,所以如果它很慢也可以,因为我没有使用它,但是我想学习如何解决这样的问题

我用的方程式是: //余数=分子-商x分母

示例:

value1 = 12500E20
value2 = 11300E0
result = value1 % value2
Expected result = 4200
Actual result = 53000E14
When full precision used (Slower) = 4200
        public static HNumber Remainder(HNumber left, HNumber right)
        {
            //Remainder = Numerator - Quotient x Denominator 
            if (right.IsZero)
                throw new DivideByZeroException("The Divisor is zero");

            int digitDiff = left.Precision - (left.DigitCount - right.DigitCount);
            digitDiff = Math.Max(0, digitDiff);
            left.Mantissa *= BigInteger.Pow(10, digitDiff);
            left.Truncate(left.DigitCount + digitDiff + left.Exponent);
            BigInteger mantissa = BigInteger.Divide(tmpLeft.Mantissa, right.Mantissa);
            int exponent = left.Exponent - right.Exponent - digitDiff;
            HNumber quotient = new HNumber(mantissa, exponent);

            HNumber qd = Multiply(quotient, right);
            HNumber result = Subtract(left, qd);
            return result;
        }
代码:

value1 = 12500E20
value2 = 11300E0
result = value1 % value2
Expected result = 4200
Actual result = 53000E14
When full precision used (Slower) = 4200
        public static HNumber Remainder(HNumber left, HNumber right)
        {
            //Remainder = Numerator - Quotient x Denominator 
            if (right.IsZero)
                throw new DivideByZeroException("The Divisor is zero");

            int digitDiff = left.Precision - (left.DigitCount - right.DigitCount);
            digitDiff = Math.Max(0, digitDiff);
            left.Mantissa *= BigInteger.Pow(10, digitDiff);
            left.Truncate(left.DigitCount + digitDiff + left.Exponent);
            BigInteger mantissa = BigInteger.Divide(tmpLeft.Mantissa, right.Mantissa);
            int exponent = left.Exponent - right.Exponent - digitDiff;
            HNumber quotient = new HNumber(mantissa, exponent);

            HNumber qd = Multiply(quotient, right);
            HNumber result = Subtract(left, qd);
            return result;
        }
这段代码可以工作并给出准确的结果,但正如我前面所说的,它的速度慢(与其他函数相比),而且内存效率不高

GitHub上的完整代码: (有点乱,对不起)


最后的问题是,有没有其他方法可以不用left.Truncate(left.DigitCount+digitDiff+left.Exponent)实现它?

使用大整数。如果需要十进制值,则乘以分子,并以10的相同幂表示。完成后,将结果除以相同的十次方。