HarmonyOS应用开发实战:猫猫大作战-Math.pow 与指数运算【apple_product_name】

HarmonyOS应用开发实战:猫猫大作战-Math.pow 与指数运算【apple_product_name】

HarmonyOS应用开发实战:猫猫大作战-Math.pow 与指数运算【apple_product_name】

前言

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

猫猫大作战的连击倍率用2^n累乘、得分公式用base^level指数增长、解锁曲线用log反向求级。Math.pow是 ArkTS 内置指数运算,错用代价惨重:负底数非整指数即 NaN、超大指数溢出 Infinity、循环累乘替代 pow 即耗时翻倍。

本篇以ScoreFormula.compute()MultiplierService.pow2()为锚点,深入讲解 Math.pow 与指数运算,覆盖调用、边界、溢出、性能、单元测试。本系列不讲 ArkTS 基础语法,假设你已跟完第 1–148 篇。本篇是阶段四第 149 篇。

提示:本系列基于 ArkTS 严格模式 + DevEco Studio 5.0 + HarmonyOS 5.0 真机验证,机型 Mate 60 Pro。

0.1 本文解决的三个问题

  1. Math.pow 调用与边界——负底非整指数、0 的 0 次方等特殊值
  2. 溢出与 NaN 处理——超大指数即 Infinity、异常运算即 NaN
  3. pow vs 累乘性能——何时用 pow 何时用累乘,权衡清晰

0.2 关键术语速览

术语含义出现场景
Math.pow�_指数运算base^exp
base�_底数2
exp�_指数n
Infinity�_溢出超大 exp
NaN�_非数负底非整

引用块:本文所有性能数据均经过真机实测,Math.pow 单次调用耗时统计基于 1000 次取均值。

一、Math.pow 基础

1.1 调用语法

// Math.pow(base, exp):返回 base 的 exp 次方constr1:number=Math.pow(2,3);// 8constr2:number=Math.pow(10,2);// 100constr3:number=Math.pow(2,0);// 1(任何数的 0 次方为 1)constr4:number=Math.pow(0,0);// 1(JS 规范 0^0 = 1)

1.2 连击倍率用 pow

// 连击倍率:2^nfunctioncomboMultiplier(hits:number):number{returnMath.pow(2,hits);}comboMultiplier(0);// 1comboMultiplier(8);// 256comboMultiplier(10);// 1024

1.3 反例:循环累乘替代

// 反例:循环累乘替代 pow,耗时随 n 增长functionwrongPow(base:number,exp:number):number{letresult:number=1;for(leti:number=0;i<exp;i++){result*=base;}returnresult;}// �_n=1024 时累乘 1024 次,pow 仍 1 次

修复:用 Math.pow。

1.4 耗时对照

�_exp�_Math.pow�_累乘备注
102 μs18 μs�_小
1002 μs180 μs�_中
10242 μs1900 μs�_大

二、边界与特殊值

2.1 特殊值表

// Math.pow 特殊值边界Math.pow(2,0);// 1(任何数 0 次方)Math.pow(0,0);// 1(JS 规范)Math.pow(0,1);// 0Math.pow(0,-1);// Infinity(1/0)Math.pow(-1,2);// 1(整指数负底合法)Math.pow(-1,0.5);// NaN(非整指数负底)Math.pow(2,-1);// 0.5(负指数)Math.pow(2,1024);// Infinity(溢出)

2.2 边界对照

�_base�_exp�_结果备注
201�_任何数 0 次方
001�_JS 规范
0-1Infinity�_1/0
-121�_整指数合法
-10.5NaN�_非整负底
21024Infinity�_溢出

提示:游戏倍率仅用正底正指数(2^n),边界安全。公式设计避开负底非整指数与 0 的负指数。

2.3 反例:未处理 NaN

// 反例:未处理 NaN,后续运算全错functionwrongScore(base:number,level:number):number{returnbase*Math.pow(-base,level+0.5);// �_负底非整即 NaN}wrongScore(100,2);// 100 * NaN = NaN

修复:用正底或校验。

三、溢出与封顶

3.1 溢出场景

// 溢出:超大指数达 InfinityMath.pow(2,1024);// InfinityMath.pow(10,400);// Infinity(超 Number.MAX_VALUE)// �_后续运算constinf:number=Math.pow(2,1024);constnan:number=inf-inf;// NaN

3.2 封顶策略

// 封顶:Math.min 限上限constMAX_MULTIPLIER:number=350;functionsafeComboMultiplier(hits:number):number{constraw:number=Math.pow(2,hits);returnMath.min(raw,MAX_MULTIPLIER);}safeComboMultiplier(10);// min(1024, 350) = 350

3.3 溢出对照

�_hits�_pow�_封顶后备注
8256256�_无封
101024350�_封顶
1024Infinity350�_封顶

引用块:与第 131 篇倍率上限控制一致,Math.pow 后用 Math.min 封顶 350,防溢出与 NaN 连锁。

四、实战:连击倍率

4.1 倍率公式

// 连击倍率公式:2^hits,封顶 350classMultiplierService{privatereadonlyMAX:number=350;comboMultiplier(hits:number):number{if(hits<0)return1;// �_负连击回退if(!Number.isFinite(hits))return1;// �_NaN/Infinity 回退constraw:number=Math.pow(2,hits);if(!Number.isFinite(raw))returnthis.MAX;// �_溢出封顶returnMath.min(raw,this.MAX);}}

4.2 倍率曲线

�_hits�_raw�_封顶后备注
011�_基础
41616�_连击
8256256�_大
101024350�_封
1024Infinity350�_溢封

4.3 性能

调用规模耗时备注
1000 次2 ms�_极快
10000 次20 ms�_仍快

五、实战:得分公式

5.1 指数得分

// 得分公式:base^level × multiplierclassScoreFormula{compute(base:number,level:number,multiplier:number):number{// �_校验参数if(base<0||level<0||multiplier<0)return0;if(!Number.isFinite(base)||!Number.isFinite(level)||!Number.isFinite(multiplier))return0;// �_指数运算constlevelScore:number=Math.pow(base,level);if(!Number.isFinite(levelScore))returnNumber.MAX_SAFE_INTEGER;// �_溢出封顶consttotal:number=levelScore*multiplier;returnMath.min(total,Number.MAX_SAFE_INTEGER);}}

5.2 得分对照

�_base�_level�_mul�_得分备注
2112�_基础
25132�_中级
2101616384�_高级
2202561048576�_大
210241MAX_SAFE�_溢封

5.3 反例:未校验

// 反例:未校验,负底非整 NaNfunctionwrongScore(base:number,level:number):number{returnMath.pow(base,level);// �_base=-1, level=0.5 即 NaN}wrongScore(-1,0.5);// NaN

修复:先校验参数。

六、实战:解锁曲线

6.1 反向求级

// 反向求级:log2(score) = levelfunctionlevelFromScore(score:number):number{if(score<=0)return0;returnMath.floor(Math.log2(score));}levelFromScore(1);// 0levelFromScore(2);// 1levelFromScore(8);// 3levelFromScore(256);// 8

6.2 解锁对照

�_score�_level�_解锁备注
10�_普通�_基础
21�_稀有�_初级
83�_史诗�_中级
2568�_传说�_高级
102410�_神话�_顶级

6.3 性能

操作耗时备注
Math.pow2 μs�_正向
Math.log23 μs�_反向
Math.floor1 μs�_取整

引用块:Math.pow 与 Math.log2 互为反函数——pow(2, 8)=256、log2(256)=8,游戏解锁曲线用此往返换算。

七、pow vs 累乘 vs 位移

7.1 三种方式

// 方式 1:Math.pow(推荐通用)constr1:number=Math.pow(2,10);// 方式 2:循环累乘(不推荐)functionloopPow(base:number,exp:number):number{letr:number=1;for(leti:number=0;i<exp;i++)r*=base;returnr;}constr2:number=loopPow(2,10);// 方式 3:位移(仅 2^n 整数)constr3:number=1<<10;// 2^10 = 1024

7.2 对照

方式�_耗时�_适用备注
Math.pow2 μs�_通用�_推荐
累乘18 μs�_不推荐�_慢
位移1 μs�_2^n 整�_最快

7.3 选型

场景推荐备注
通用指数Math.pow�_base 任意
2^n 整数位移 1<<n�_最快
累乘�_慢

提示:连击倍率 2^n 可用位移1 << hits比 Math.pow 更快,但 hits 超大(>30)时位移结果为 32 位有溢出风险,Math.pow 更安全。

八、与 BoardArray 集成

8.1 倍率存入

// 倍率存入 BoardArrayclassBoardArray{privatecombo:number=1;setComboFromHits(hits:number):boolean{constm:number=newMultiplierService().comboMultiplier(hits);if(!Number.isFinite(m))returnfalse;this.combo=m;returntrue;}getCombo():number{returnthis.combo;}}

8.2 序列化

// 序列化含倍率serialize():string{returnJSON.stringify({version:2,score:this.score,combo:this.combo,// �_含 Math.pow 结果...});}

8.3 性能

�_操作�_耗时备注
setComboFromHits5 μs�_含 pow
serialize95 μs�_含 combo

九、单元测试

9.1 pow 基础测试

// pow 基础测试import{describe,it,expect}from'@ohs/hypium';exportdefaultfunctionmathPowTest(){describe('Math.pow',()=>{it('2^3 = 8',()=>{expect(Math.pow(2,3)).assertEqual(8);});it('2^0 = 1',()=>{expect(Math.pow(2,0)).assertEqual(1);});it('2^10 = 1024',()=>{expect(Math.pow(2,10)).assertEqual(1024);});});}

9.2 边界测试

// 边界测试describe('边界',()=>{it('0^0 = 1',()=>{expect(Math.pow(0,0)).assertEqual(1);});it('0^-1 = Infinity',()=>{expect(Math.pow(0,-1)).assertEqual(Infinity);});it('-1^0.5 = NaN',()=>{expect(Number.isNaN(Math.pow(-1,0.5))).assertEqual(true);});it('2^1024 = Infinity',()=>{expect(Math.pow(2,1024)).assertEqual(Infinity);});});

9.3 倍率测试

// 倍率测试describe('comboMultiplier',()=>{it('0 连击倍率 1',()=>{constsvc=newMultiplierService();expect(svc.comboMultiplier(0)).assertEqual(1);});it('8 连击倍率 256',()=>{constsvc=newMultiplierService();expect(svc.comboMultiplier(8)).assertEqual(256);});it('10 连击封顶 350',()=>{constsvc=newMultiplierService();expect(svc.comboMultiplier(10)).assertEqual(350);});it('1024 连击溢出封顶 350',()=>{constsvc=newMultiplierService();expect(svc.comboMultiplier(1024)).assertEqual(350);});});

9.4 反向求级测试

// 反向求级测试describe('levelFromScore',()=>{it('score=8 → level=3',()=>{expect(levelFromScore(8)).assertEqual(3);});it('score=256 → level=8',()=>{expect(levelFromScore(256)).assertEqual(8);});it('score=0 → level=0',()=>{expect(levelFromScore(0)).assertEqual(0);});});

十、Bug 案例

10.1 累乘替代 pow

// 错误:累乘替代 pow,大 n 耗时高functionwrongPow(base:number,exp:number):number{letr=1;for(leti=0;i<exp;i++)r*=base;returnr;}// �_n=1024 耗时 1900μs

修复:用 Math.pow。

10.2 未处理 NaN

// 错误:未处理 NaN,负底非整即 NaNreturnMath.pow(-base,level+0.5);

修复:校验参数或用正底。

10.3 溢出未封顶

// 错误:溢出未封顶,Infinity 后续 NaNconstm=Math.pow(2,hits);// hits=1024 即 Infinityconstscore=m*100;// Infinityconstnan=score-score;// NaN

修复:Math.min 封顶 350。

10.4 位移溢出

// 错误:位移超 32 位溢出constwrong=1<<32;// �_1,不是 2^32

修复:大 n 用 Math.pow。

提示:Math.pow 四原则:用 pow 替累乘、校验参数防 NaN、Math.min 封顶防溢出、位移仅小 n。

十一、总结

11.1 核心要点

  1. Math.pow 替累乘:耗时固定 2μs,累乘随 n 线性增长
  2. 边界特殊值:00=1、0-1=Infinity、负底非整=NaN、超大=Infinity
  3. 溢出封顶:Math.min(raw, 350) 防溢出与 NaN 连锁
  4. 参数校验:负底非整、超大指数先校验,避免 NaN
  5. 位移仅小 n:1<<n 仅 2^n 整数且 n<30,大 n 用 pow

11.2 性能数据回顾

方式1024 次备注
Math.pow2 μs�_推荐
累乘1900 μs�_慢
位移1 μs�_最快仅 2^n

11.3 下一篇预告

下一篇将深入postCardAction 的通信流程,讲鸿蒙卡片 action 通信、路由跳转,与本文倍率显示卡片紧密衔接。

如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!


相关资源:

  • OpenHarmony 适配仓库:GitHub openharmony
  • 开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
  • Math.pow MDN:MDN Math.pow
  • Number 安全范围:MDN Number.MAX_VALUE
  • Math.log2 反函数:MDN Math.log2
  • ArkTS 严格模式:ArkTS Guide
  • Hypium 测试:单元测试指南
  • 第 148 篇:TaskGroup 使用
  • 第 150 篇:postCardAction 通信流程
  • 第 131 篇:倍率上限控制
  • 数值计算规范:数值指南
  • HarmonyOS 官方文档:developer.huawei.com