You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中如何将BigInteger转换为带两位小数的浮点数?BigDecimal库不可用

解决方案:Unity点击器游戏BigInteger货币的两位小数格式化问题

核心问题分析

你原代码的关键问题是BigInteger转decimal时会溢出——decimal类型有最大范围限制(约7.9×10²⁸),而你的除数数组里包含10⁵²这种超大值,当货币数值超过decimal上限时,强制转换会直接抛出异常。同时,直接用浮点数处理还可能带来精度丢失的问题。

下面给出两种实用解决方案,全程用整数运算规避这些问题:


方案1:用最小面额整数存储(推荐)

点击器游戏最稳妥的做法是把货币单位设为最小面额(比如“分”),用BigInteger存储总分数,所有经济计算都用整数,彻底避免小数精度问题。格式化时再转换为带两位小数的金额:

// totalCents是存储的总分数,例如1234代表12.34元
public string FormatMoney(BigInteger totalCents)
{
    // 拆分元和分
    BigInteger dollars = totalCents / 100;
    int cents = (int)(totalCents % 100);

    // 小额直接显示
    if (dollars < 1000)
    {
        return $"{dollars}.{cents:D2}";
    }

    BigInteger[] divisors = {
        BigInteger.Pow(10, 3),
        BigInteger.Pow(10, 6),
        BigInteger.Pow(10, 9),
        BigInteger.Pow(10, 12),
        BigInteger.Pow(10, 15),
        BigInteger.Pow(10, 18),
        BigInteger.Pow(10, 21),
        BigInteger.Pow(10, 24),
        BigInteger.Pow(10, 27),
        BigInteger.Pow(10, 30),
        BigInteger.Pow(10, 33),
        BigInteger.Pow(10, 36),
        BigInteger.Pow(10, 39),
        BigInteger.Pow(10, 42),
        BigInteger.Pow(10, 45),
        BigInteger.Pow(10, 48),
        BigInteger.Pow(10, 52)
    };

    string[] suffixes = {"K", "M", "B", "T", "aa", "ab", "ac", "ad", "ae", "af", "ag", "ah", "ai", "aj", "ak", "al" };

    // 匹配对应的后缀
    for (int i = 0; i < divisors.Length; i++)
    {
        if (dollars < divisors[i] * 1000)
        {
            // 用整数运算计算带两位小数的结果,避免溢出
            BigInteger scaled = dollars * 100 / divisors[i];
            string wholePart = (scaled / 100).ToString();
            string decimalPart = (scaled % 100).ToString("D2");
            return $"{wholePart}.{decimalPart}{suffixes[i]}";
        }
    }

    // 处理最大数值
    int lastIndex = divisors.Length - 1;
    BigInteger finalScaled = dollars * 100 / divisors[lastIndex];
    string finalWhole = (finalScaled / 100).ToString();
    string finalDecimal = (finalScaled % 100).ToString("D2");
    return $"{finalWhole}.{finalDecimal}{suffixes[lastIndex]}";
}

这种方式从根源上解决了小数存储的精度问题,商品定价直接用分数(比如1234就是12.34元),所有运算都是整数,不会出现精度丢失或溢出。


方案2:直接格式化BigInteger为带两位小数的字符串(针对已用元存储的场景)

如果已经用BigInteger存储的是元(比如12代表12.00元),需要显示带两位小数的格式,可通过纯整数运算处理,避免浮点数转换:

public string FormatMoney(BigInteger value)
{
    // 小额直接显示两位小数
    if (value < 1000)
    {
        return $"{value}.00";
    }

    BigInteger[] divisors = {
        BigInteger.Pow(10, 3),
        BigInteger.Pow(10, 6),
        BigInteger.Pow(10, 9),
        BigInteger.Pow(10, 12),
        BigInteger.Pow(10, 15),
        BigInteger.Pow(10, 18),
        BigInteger.Pow(10, 21),
        BigInteger.Pow(10, 24),
        BigInteger.Pow(10, 27),
        BigInteger.Pow(10, 30),
        BigInteger.Pow(10, 33),
        BigInteger.Pow(10, 36),
        BigInteger.Pow(10, 39),
        BigInteger.Pow(10, 42),
        BigInteger.Pow(10, 45),
        BigInteger.Pow(10, 48),
        BigInteger.Pow(10, 52)
    };

    string[] suffixes = {"K", "M", "B", "T", "aa", "ab", "ac", "ad", "ae", "af", "ag", "ah", "ai", "aj", "ak", "al" };

    // 匹配对应的后缀
    for (int i = 0; i < divisors.Length; i++)
    {
        if (value < divisors[i] * 1000)
        {
            // 把保留两位小数的计算转为整数运算
            BigInteger scaled = value * 100 / divisors[i];
            string wholePart = (scaled / 100).ToString();
            string decimalPart = (scaled % 100).ToString("D2");
            return $"{wholePart}.{decimalPart}{suffixes[i]}";
        }
    }

    // 处理最大数值
    int lastIndex = divisors.Length - 1;
    BigInteger finalScaled = value * 100 / divisors[lastIndex];
    string finalWhole = (finalScaled / 100).ToString();
    string finalDecimal = (finalScaled % 100).ToString("D2");
    return $"{finalWhole}.{finalDecimal}{suffixes[lastIndex]}";
}

这个方案通过value * 100 / divisors[i]将两位小数的计算转为纯整数操作,完全规避了浮点数的精度和溢出问题,Unity中可以直接运行。

内容的提问来源于stack exchange,提问作者Mister Danila

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 15:17:07