[其他资源] 分享个第三方库BigNumber 数值升级类游戏必备 新增注意事项

  [复制链接]
1277 |16
窜稀大仙 发表于 2023-6-14 00:25:05 | 显示全部楼层 |阅读模式
本帖最后由 窜稀大仙 于 2023-7-4 23:10 编辑

做数值升级游戏到后期的数值可能会非常大,而内置的number类型的大小是有限制的 ( ±1.79769313486231e+308),超过了这个值,所有的值都会变成Infinity,伤害,血量全是这个值,数值体系直接崩坏。(别问我怎么知道的,说多了都是泪)
这时候就需要使用新的大数值类型。
TypeScript内置有BigInt类型,但无法显示小数和计算小数,这就非常麻烦,与小数相乘时需要繁琐的转换,影响效率而且代码写出来实在很难看。一不小心转换不到位,代码就会卡住(没有报错的那种卡住,蔫坏型的)。

我使用了第三方的BigNumber库,GitHub上免费的。

QQ截图2.jpg
右键打开脚本路径
QQ截图20230613234256.jpg
把我提供的这两个文件复制上,不要改名
QQ截图20230613234337.jpg
其他脚本直接import就能用
测试下123的20万次幂试试
QQ截图20230614001209.jpg
输出:
QQ截图.jpg
number彻底废柴了,BigInt累的肠子肚子都出来了,我们调教后的BigNumber则很绅士,还科学计数法了一下。
那个调教,其实就是简单设置了一下BigNumber.Config,抛弃了不必要的次幂计算精度(6位有效数字),小数点后保留3位等设置。我们不是造原子弹,不要求数值那么精确,做游戏这些精度足够用了。
可以看到调教后的BigNumber性能完爆BigInt。


另外调教版里我自己写了几个常用的常量值,这些值频繁新建的话也会影响游戏效率。
QQ截图20230614002740.jpg

游戏里除了直接显示科学计数法,要显示那种1.234K , 5.678M ,50.001T的工程计数法,BigNumber也很好实现。
我写了个方法,我也在用,可以直接拿去用。


  private  static  prefixes_bn:  Array<string>  =  [
    "", "K",  "M",  "B",  "T",  "q",  "Q",  "s",  "S",  "o",  "O",
    "d",  "D",  "u",  "U",  "g",  "G",  "i",  "I",  "n",  "N",
    "p",  "P",  "h",  "H",  "l",  "L",  "r",  "R",  "j",
    "J",  "w",  "W",  "a",  "A",  "v",  "V",  "y",  "Y",
    "c",  "C",  "z",  "Z",  "f",  "F",  "la",  "lb",  "lc",
    "ld",  "le",  "lf",  "lg",  "lh",  "li",  "lj",  "lk",  "ll",
    "lm",  "ln",  "lo",  "lp",  "lq",  "lr",  "ls",  "lt",  "!"
]
  public static re_numtext_bn(num: BigNumber): string {
    let i = 0
    let length = this.prefixes_bn.length
    if(num.lt(1000)) {
      return String(num.integerValue())
    }
    while (num.gte(1000)) {
      num = num.div(1000)
      i++
    }
    let unit = ""
    let result = num.toPrecision(4)
    if(i < length) {
      unit = this.prefixes_bn[i]
    } else {
      unit = "#" + String(i - length)
    }
    // 删除末尾的零和小数点
    result = result.replace(/\.?0+$/, "")
    return result + unit
  }

另外需要注意,
1 在存档时,BigNumber不要直接存,要转换成string,而且最好用.toPrecision()截取有效数字再存,否则字符串会过长。
例如
data_gold = String(gold.toPrecision(10))
//截取10位有效数字后转成文本存档

当然用的时候要转换回来,gold = BigNumber(data_gold)

2 新坑,.pow()的指数参数不要填小数,例如某数的1.5次方,不能这样用,不报错但会卡住。

附件:

bignumber文件原版.rar (31.77 KB, 下载次数: 57)
更多图片 小图 大图
组图打开中,请稍候......
回复

使用道具 举报

窜稀大仙楼主 发表于 2023-6-14 00:26:49 | 显示全部楼层
这是网上粘来的bignumber常用方法:
加法
1
COPYnew BigNumber(0.1).plus(new BigNumber(0.2)).toNumber()
减法
1
COPYnew BigNumber(0.2).minus(new BigNumber(0.1)).toNumber()
乘法
1
COPYnew BigNumber(0.2).multipliedBy(new BigNumber(0.1)).toNumber()
除法
1
COPYnew BigNumber(0.2).dividedBy(new BigNumber(0.1)).toNumber()
除法-取整
5/2 为 2 余数 1,这里显示这个整数2
1
COPYnew BigNumber(1).dividedToIntegerBy(new BigNumber(0.9)).toNumber()
除法-取余
5/2 为 2 余数 1,这里显示这个余数1
1
COPYnew BigNumber(1).modulo(new BigNumber(0.9)).toNumber()
等于
1
COPYnew BigNumber(0.001).eq(new BigNumber(0.001))
大于
1
COPYnew BigNumber(0.002).gt(new BigNumber(0.001))
大于等于
1
COPYnew BigNumber(0.002).gte(new BigNumber(0.002))
小于
1
COPYnew BigNumber(0.001).lt(new BigNumber(0.002))
小于等于
1
COPYnew BigNumber(0.002).lte(new BigNumber(0.002))
绝对值
1
COPYnew BigNumber(-0.002).abs()
保存几位小数
1
COPYnew BigNumber(-0.002).toFixed(2)
转换为数字
1
COPYnew BigNumber(-0.002).toNumber()

回复

使用道具 举报

汽汽汽汽水 发表于 2023-6-14 00:42:21 | 显示全部楼层
感谢分享哇
回复

使用道具 举报

Othanse 发表于 2023-6-14 08:58:00 | 显示全部楼层
哇塞 厉害的
回复

使用道具 举报

届かない恋 发表于 2023-6-14 10:12:47 | 显示全部楼层
刚好用的上
回复

使用道具 举报

喵喵哭唧唧 发表于 2023-6-14 12:03:05 | 显示全部楼层
大佬,你是我的偶像
回复

使用道具 举报

吃到苦就是得到了甜 发表于 2023-6-14 18:07:02 | 显示全部楼层
哇哇哇
回复

使用道具 举报

美颜扛把子 发表于 2023-6-17 13:53:19 | 显示全部楼层

这个地方有报错 image.png
回复

使用道具 举报

窜稀大仙楼主 发表于 2023-6-17 13:55:34 | 显示全部楼层

image.png

应该是这个 粘贴时候中括号不知道怎么丢了
回复

使用道具 举报

美颜扛把子 发表于 2023-6-17 13:55:53 | 显示全部楼层
private static prefixes_bn: Array<string> = [
        "", "K", "M", "B", "T", "q", "Q", "s", "S", "o", "O",
        "d", "D", "u", "U", "g", "G", "i", "I", "n", "N",
        "p", "P", "h", "H", "l", "L", "r", "R", "j",
        "J", "w", "W", "a", "A", "v", "V", "y", "Y",
        "c", "C", "z", "Z", "f", "F", "la", "lb", "lc",
        "ld", "le", "lf", "lg", "lh", "li", "lj", "lk", "ll",
        "lm", "ln", "lo", "lp", "lq", "lr", "ls", "lt", "!"
    ];

    public static re_numtext_bn(num: number): string {
        let i = 0;
        let length = this.prefixes_bn.length;
        if (num < 1000) {
            return String(num);
        }
        while (num >= 1000) {
            num = num / 1000;
            i++;
        }
        let unit = "";
        let result = num.toFixed(4);
        if (i < length) {
            unit = this.prefixes_bn[i];
        } else {
            unit = "#" + String(i - length);
        }
        // 删除末尾的零和小数点
        result = result.replace(/\.?0+$/, "");
        return result + unit;
    }
回复

使用道具 举报

热门版块
快速回复 返回顶部 返回列表