我的类中有一个更新用户体验的私有方法。
首先,我创建了基于giveExp的contentLength (string.length)
在这种方法中,我有exp:(Math.sqrt(2 * user.xp - 175) + 25) / 10;的计数级别公式。
我也需要告诉球员他们已经升级了。
全码
private updateXp(
contentLength: number,
channel: Readonly<WritableChannel>,
xp: string
) {
const giveExp = Math.round(contentLength * 3 * 0.1);
let userXp = Number.parseInt(xp, 10);
const level = (Math.sqrt(2 * userXp - 175) + 25) / 10;
userXp += giveExp < 15 ? giveExp : 15;
const nowLevel = (Math.sqrt(2 * userXp - 175) + 25) / 10;
if (level.toFixed(0) < nowLevel.toFixed(0)) {
void channel.send("Level up");
}
return String(userXp);
}发布于 2022-03-14 13:34:15
我发现你的代码很难读懂。
在评论中,OP说:“当一个数字xp变得非常大时,它只能作为BigInt工作。我的数据库中也有一个字符串类型。”
parseInt函数将其第一个参数转换为字符串,解析该字符串,然后返回整数,如果大于Number.MAX_VALUE,则返回无限。一个数字被转换成定点表示法,除非大数(超过20位数)被转换成指数表示法.BigInt被转换为定点表示法.parseInt函数只返回指数表示法的整数部分。将xp解析为BigInt(xp)。
计算出水平公式,以清楚地表明您使用的是相同的公式。对于整数数值的比较,不要比较字符串。使用Math.round。
JavaScript数字不支持复数。如果(2 * xp - 175) <0或xp < 87.5,则级别公式表达式Math.sqrt(2 * xp - 175)传播NaN。数学适用于数字类型。级别公式表达式Math.sqrt(2 *XP-175)只处理小于或等于(Number.MAX_VALUE / 2)或8.988465674311579e+307的xp值。
二进制浮点数(IEEE 754)是一种近似,包括0.1.为了得到更准确的结果,不要乘以0.1,除以10。
重新排序代码以将相关语句分组在一起。
有时你使用xp,有时你使用exp。一致使用xp (或exp)。
你有水平和nowLevel。为了清晰起见,请使用oldLevel和newLevel。
对于数学公式,使用Math.min代替条件(三元)运算符。
由于操作是“级别向上”,所以将测试反转到newLevel > oldLevel。
对于缩小的代码,使用间距和缩进来增强可读性。
function updateXp(
contentLength,
channel,
xp) {
function levelFormula(xp) {
return Math.round((Math.sqrt(2 * xp - 175) + 25) / 10);
}
let userXp = Number.parseInt(BigInt(xp), 10);
const oldLevel = levelFormula(userXp);
const giveXp = Math.round(contentLength * 3 / 10);
userXp += Math.min(giveXp, 15);
const newLevel = levelFormula(userXp);
if (newLevel > oldLevel) {
void channel.send("Level up");
}
return String(userXp);
}https://codereview.stackexchange.com/questions/274902
复制相似问题