文章目录
- 背景
- 方法总览
- 什么是往返验证?
- C→F→C 往返验证
- C→K→C 往返验证
- 浮点数精度的细节
- 滑块实时显示精度验证
- 实际开发中的精度建议
- TempUtil 批量转换的完整对照表
- 写在最后
背景
近期发现一款很有意思的HarmonyOS 三方库, 地址 @pura/harmony-utils(V1.4.0) , 作者是"桃花镇童长老", 我这里也是直接通过该作者公布的源码进行案例编写进行,写了到目前写了一部分demo ,感觉确实很有帮助,这里呢也是开始写一个系列的演示demo 供大家参考。如有帮助可以在OpenHarmony中进行下载安装进行使用哦
案例demo导航展示
↓↓↓↓↓↓接下来言归正传 ↓↓↓↓
方法总览
什么是往返验证?
往返验证就是:原始值 → 转换 → 再转换回来,看最终结果和原始值的误差有多小。
如果精度够高,误差应该趋近于 0。
C→F→C 往返验证
this.Btn('C(25) → F → C 往返验证','#9B59B6',()=>{constoriginal=25;constf=TempUtil.C2F(original);constback=TempUtil.F2C(f);this.addLog(`C(${original}) → F(${f.toFixed(4)}) → C(${back.toFixed(4)}) 误差:${Math.abs(back-original).toFixed(10)}`);})运行结果:
C(25) → F(77.0000) → C(25.0000) 误差:0.0000000000误差是0.0000000000(10位小数都是0),精度非常高。
原理分析:
C2F公式:F = C × 9/5 + 32,即25 × 9/5 + 32 = 45 + 32 = 77F2C公式:C = (F - 32) × 5/9,即(77 - 32) × 5/9 = 45 × 5/9 = 25
这两个公式互为逆运算,数学上完全互逆,所以误差极小(受限于 IEEE 754 双精度浮点数精度,但实际是 0)。
C→K→C 往返验证
this.Btn('C(100) → K → C 往返验证','#8E44AD',()=>{constoriginal=100;constk=TempUtil.C2K(original);constback=TempUtil.K2C(k);this.addLog(`C(${original}) → K(${k.toFixed(4)}) → C(${back.toFixed(4)}) 误差:${Math.abs(back-original).toFixed(10)}`);})运行结果:
C(100) → K(373.1500) → C(100.0000) 误差:0.0000000000同样是完美精度,误差为 0。
原理分析:
C2K公式:K = C + 273.15,即100 + 273.15 = 373.15K2C公式:C = K - 273.15,即373.15 - 273.15 = 100
加减法的逆运算更简单,精度损失基本为零。
浮点数精度的细节
虽然上面的验证误差都是 0,但你可能在某些特殊值上看到极小的浮点误差。这是正常现象。
什么是浮点误差?
计算机用二进制存储数字,大部分十进制小数无法精确表示为有限位二进制。比如0.1 + 0.2在 JavaScript 里等于0.30000000000000004,而不是0.3。
举个温度转换的极端例子:
constc=37.7;constf=TempUtil.C2F(c);constback=TempUtil.F2C(f);// back 可能是 37.700000000000003 而不是 37.7// 误差约为 2.8e-15,极小这种误差在实际应用里通常不影响显示(保留2位小数就消除了),也不影响业务逻辑(比较温度高低不会受此影响)。
滑块实时显示精度验证
Demo 里的滑块还展示了实时转换的精度:
@StatesliderC:number=0;Text(`当前:${this.sliderC}°C =${TempUtil.C2F(this.sliderC).toFixed(2)}°F =${TempUtil.C2K(this.sliderC).toFixed(2)}K`).fontSize(14).fontColor('#1a1a1a').width('100%').textAlign(TextAlign.Center)这里用了.toFixed(2)保留2位小数,确保显示整洁,不会出现一长串小数位。
实际开发中的精度建议
1. 显示时用.toFixed()控制位数
// 对用户显示,保留1-2位小数就够了constfahrenheit=TempUtil.C2F(temperature);constdisplayText=`${fahrenheit.toFixed(1)}°F`;2. 比较大小不用担心精度
constbodyTemp=37.0;constmeasureTemp=TempUtil.F2C(98.6);// 转换结果约 37.00if(Math.abs(measureTemp-bodyTemp)<0.1){// 体温正常}3. 科学计算需要保留更多位数
// 工程计算,保留4位constk=TempUtil.C2K(absoluteZero);console.log(k.toFixed(4));// 0.0000TempUtil 批量转换的完整对照表
这是 Demo 里几个常见温度值的转换结果汇总:
| 摄氏度 (°C) | 华氏度 (°F) | 开尔文 (K) | 含义 |
|---|---|---|---|
| -273.15 | -459.67 | 0.00 | 绝对零度 |
| -40 | -40.00 | 233.15 | 两单位数值相等点 |
| 0 | 32.00 | 273.15 | 水的冰点 |
| 20 | 68.00 | 293.15 | 室温 |
| 37 | 98.60 | 310.15 | 人体体温 |
| 100 | 212.00 | 373.15 | 水的沸点 |
写在最后
TempUtil 的温度转换精度非常高,日常使用完全不用担心精度问题。
往返验证的结果告诉我们:这些方法实现了数学意义上的精确互逆,误差在 JavaScript 双精度浮点数的精度范围内(即接近于0)。
实际开发中记住用.toFixed()控制显示精度,这不是为了弥补计算误差,而是为了更好的用户体验。