【问题标题】:BigInteger string representation with decimal places带小数位的 BigInteger 字符串表示
【发布时间】:2012-02-22 20:41:54
【问题描述】:

我正在尝试创建一个大整数除以某物时的十进制表示。以下是执行此操作的代码,基本上我希望精度为 2 位。

    public string GetDecimal(BigInteger bigInteger,int divisor)
    {
        var remainder   = BigInteger.Remainder(bigInteger, divisor);
        var dividend    = BigInteger.Divide(bigInteger, divisor);

        var d = ((double)remainder / divisor);
        var decimalPart = Math.Round(d, 2);
        var retValue = dividend + decimalPart.ToString(".00");
        return retValue;
    }
}

请问有更好的方法吗?

谢谢, -迈克

【问题讨论】:

  • 你可以用一个 DivRem 调用来完成前两行 -- msdn.microsoft.com/en-us/library/…
  • 变量dividend 应命名为quotient。 “股息”是指“被分割的东西”;被除数类似于分数的分子。换句话说,quotient = dividend / divisor.
  • 您的代码实际上已损坏。用999/1000进行测试

标签: c# c#-4.0 biginteger


【解决方案1】:

您可能不应该转换类型并自己进行长除法。这应该适用于任何 BigInteger 值。

我相信这里还有改进的余地...

public string GetDecimal(BigInteger bigInteger, int divisor)
{
    BigInteger remainder;
    var quotient = BigInteger.DivRem(bigInteger, divisor, out remainder);

    const int decimalPlaces = 2;
    var decimalPart = BigInteger.Zero;
    for(int i = 0; i < decimalPlaces; i++)
    {
        var div = (remainder*10)/divisor;

        decimalPart *= 10;
        decimalPart += div;

        remainder = remainder*10 - div*divisor;
    }

    var retValue = quotient.ToString() + "." + decimalPart.ToString(new string('0', decimalPlaces));
    return retValue;
}

【讨论】:

  • 这输出的精度是否为 2 个零?我只得到一个零的精度,比如:7.0 而不是 7.00。
  • @Mike:我没有测试尾随零。我会查的。 --编辑以解决所有零问题
【解决方案2】:

.net decimal 的内置类型是 128 位,可与其他类型的类似舍入结构一起使用。这个数字还不够大吗?

【讨论】:

  • 不,不是。因此选择 BigInteger。
  • 好的,我假设您正在使用它进行货币计算(因为您要四舍五入到小数点后 2 位),我建议您使用 decimal 而不是 double 来防止精度问题.
  • @Matthew 如果他四舍五入到小数点后两位,他不会受到double 的精度问题的影响,直到您超过小数点后十位才会显示。
【解决方案3】:

而不是对其进行数学运算,尤其是使用精度较低的类型,例如 double。 只需构建一个除了最后两位之外的所有数字的字符串,附加一个小数点,然后放入最后一个。

例如类似的东西

int precision = 2;
negative = 0;
if (bigInteger < 0)
{
   negative = 1;
}
String strValue = bigInteger.ToString().PadRight(precision + negative + 1,'0');
return strValue.Insert(strValue.Length - precision, ".");

【讨论】:

    【解决方案4】:
    var s=((bigInteger*200+divisor)/(2*(BigInteger)divisor)).ToString();
    return s.Insert(".",s.Length-2);
    

    此代码仅适用于正值,并使用AwayFromZero 中点舍入。我也不关心本地化问题。

    【讨论】:

      猜你喜欢
      • 2018-05-11
      • 2018-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-14
      相关资源
      最近更新 更多