繁体   English   中英

在 C# 中减少 BigInteger 值

[英]Reducing a BigInteger value in C#

我对使用 BigIntegers 有点陌生,并尝试了一些东西来让这个系统正常工作,但目前感觉有点卡住,真的很感激在正确的方向或解决方案上的推动。

我目前正在开发一个系统,该系统将 BigInteger 值减少为更易读的形式,这在我当前的实现中运行良好,但我想进一步扩展它以实现小数。

为了更好地展示我正在尝试的内容,我将其分解。

在这种情况下,我们有一个接受 BigInteger 并将其作为字符串返回的方法:

public static string ShortenBigInt (BigInteger moneyValue)

考虑到这一点,当诸如10,000 之类的数字传递给此方法时,将返回10k 1,000,000相同,将返回1M

这是通过执行以下操作来完成的:

for(int i = 0; i < prefixes.Length; i++)
{
     if(!(moneyValue >= BigInteger.Pow(10, 3*i)))
     {
         moneyValue = moneyValue / BigInteger.Pow(10, 3*(i-1));

         return moneyValue + prefixes[i-1];
     }
 }

该系统的工作方式是从前缀数组中抓取一个字符串,并将数字缩减为最简单的形式,然后将两者结合起来,并在该前缀范围内返回它。

因此,在这种情况下,我的问题是:我如何以同样的方式返回它,通过100,000将返回100k ,但执行类似1,111,111 的操作将返回1.11M

目前,通过1,111,111M返回1M ,但我希望附加.11标记。 不超过 2 位小数。

我最初的想法是将大整数转换为字符串,然后将前几个字符分块为新字符串并在其中解析小数,但由于前缀在值达到第 1000 个标记之前不会改变,因此很难判断何时放置小数位。

我的下一个想法是使用 BigInteger.Log 将值减少为十进制友好数字并进行简单的除法以获得十进制形式的值,但这样做似乎不适用于我的实现。

该系统应该动态地适用于以下前缀:

k, M, B, T, qd, Qn, sx, Sp, O, N, de, Ud, DD, tdD, qdD, QnD, sxD, SpD, OcD, NvD, Vgn, UVg, DVg, TVg, qtV, QnV、SeV、SPG、OVG、NVG、TGN、UTG、DTG、tsTG、qtTG、QnTG、ssTG、SpTG、OcTG、NoTG、QdDR、uQDR、dQDR、tQDR、qdQDR、QnQDR、sxQDR、SpQDR、QDDDDr qQGNT、uQGNT、dQGNT、tQGNT、qdQGNT、QnQGNT、sxQGNT、SpQGNT、OQQGNT、NQQGNT、SXGNTL

有人会碰巧知道如何做这样的事情吗? 任何语言都可以,C# 更可取,但我都擅长翻译。 先感谢您!

手动格式化它可能有点像这样:

(前缀为字符串,它是一个字符 [])

public static string ShortenBigInt(BigInteger moneyValue)
{
    string prefixes = " kMGTP";
    double m2 = (double)moneyValue;

    for (int i = 1; i < prefixes.Length; i++)
    {
        var step = Math.Pow(10, 3 * i);
        if (m2 / step < 1000)
        {
            return String.Format("{0:F2}", (m2/step)) + prefixes[i];    
        }
    }
    return "err";
}

尽管 Falco 的答案确实有效,但它不适用于所要求的内容。 这是我正在寻找的解决方案,并从朋友那里得到了一些帮助。 此解决方案将持续到您的字符串前缀数组中没有更多前缀为止。 如果确实超出了边界,则将通过返回“Infinity”来抛出和处理异常。

这个解决方案更好,因为在这个过程中没有压缩到双精度/小数。 此解决方案没有数量上限,唯一的限制是您制作/提供的前缀数量。

public static string ShortenBigInt(BigInteger moneyValue)
{
    if (moneyValue < 1000)
        return "" + moneyValue;

    try
    {
        string moneyAsString = moneyValue.ToString();
        string prefix = prefixes[(moneyAsString.Length - 1) / 3];

        BigInteger chopAmmount = (moneyAsString.Length - 1) % 3 + 1;

        int insertPoint = (int)chopAmmount;

        chopAmmount += 2;

        moneyAsString = moneyAsString.Remove(Math.Min(moneyAsString.Length - 1, (int)chopAmmount));
        moneyAsString = moneyAsString.Insert(insertPoint, ".");

        return moneyAsString + " " + prefix;
    }
    catch (Exception exceptionToBeThrown)
    {   
        return "Infinity";
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM