本帖最后由 窜稀大仙 于 2023-7-4 23:10 编辑
做数值升级游戏到后期的数值可能会非常大,而内置的number类型的大小是有限制的 ( ±1.79769313486231e+308),超过了这个值,所有的值都会变成Infinity,伤害,血量全是这个值,数值体系直接崩坏。(别问我怎么知道的,说多了都是泪)
这时候就需要使用新的大数值类型。
TypeScript内置有BigInt类型,但无法显示小数和计算小数,这就非常麻烦,与小数相乘时需要繁琐的转换,影响效率而且代码写出来实在很难看。一不小心转换不到位,代码就会卡住(没有报错的那种卡住,蔫坏型的)。
我使用了第三方的BigNumber库,GitHub上免费的。
右键打开脚本路径
把我提供的这两个文件复制上,不要改名
其他脚本直接import就能用
测试下123的20万次幂试试
输出:
number彻底废柴了,BigInt累的肠子肚子都出来了,我们调教后的BigNumber则很绅士,还科学计数法了一下。
那个调教,其实就是简单设置了一下BigNumber.Config,抛弃了不必要的次幂计算精度(6位有效数字),小数点后保留3位等设置。我们不是造原子弹,不要求数值那么精确,做游戏这些精度足够用了。
可以看到调教后的BigNumber性能完爆BigInt。
另外调教版里我自己写了几个常用的常量值,这些值频繁新建的话也会影响游戏效率。
游戏里除了直接显示科学计数法,要显示那种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, 下载次数: 103)
|
组图打开中,请稍候......
|