最近在研究帧同步的浮点计算问题,搞了好几天定点数。
测试了一下跨平台浮点问题的重灾区 sin cos sqrt。
测试了4个平台 原生 , firefox, chrome ,safari;
js的math库在4个平台上结果都不一样。
本来是测试一下定点数库的精度,偶然发现 wasm 下的 sin cos sqrt 在各个平台上却是一致的。
现在我在想,是不是可以直接用 wasm 的数学库来解决浮点数不一致问题。
有没有懂道的大佬。
测试结果 :
Native:
Chrome:
Firefox:
Safari:
测试代码:
let count = parseInt(this.editBox.string);
let sin_jsVal = 0;
let sin_fpVal = new FP;
let sin_asmVal = 0;
let cos_jsVal = 0;
let cos_fpVal = new FP;
let cos_asmVal = 0;
let sqrt_jsVal = 0;
let sqrt_fpVal = new FP;
let sqrt_asmVal = 0;
let sct_jsVal = 0;
let sct_fpVal = new FP;
let sct_asmVal = 0;
for (let i = 0; i < count; i++) {
sin_jsVal += Math.sin(i);
sin_fpVal = sin_fpVal.add(FPMath.sin(new FP(Raw._1 * BigInt(i))));
sin_asmVal += WasmTest.module.sin(i);
cos_jsVal += Math.cos(i);
cos_fpVal = cos_fpVal.add(FPMath.cos(new FP(Raw._1 * BigInt(i))));
cos_asmVal += WasmTest.module.cos(i);
sqrt_jsVal += Math.sqrt(i);
sqrt_fpVal = sqrt_fpVal.add(FPMath.sqrt(new FP(Raw._1 * BigInt(i))));
sqrt_asmVal += WasmTest.module.sqrt(i);
sct_jsVal += Math.sin(i) * Math.cos(i) * Math.sqrt(i);
sct_fpVal = sct_fpVal.add(
FPMath.sin(new FP(Raw._1 * BigInt(i)))
.mul(FPMath.cos(new FP(Raw._1 * BigInt(i))))
.mul(FPMath.sqrt(new FP(Raw._1 * BigInt(i)))));
sct_asmVal += WasmTest.module.sin(i) * WasmTest.module.cos(i) * WasmTest.module.sqrt(i);
}
this.labelTest1.string =
`
${_('sin(step)')}:
${_('js')}:\t${sin_jsVal}
${_('wasm')}:\t${sin_asmVal}
${_('fp')}:\t${sin_fpVal}
${_('fpRaw')}:${sin_fpVal.rawValue}
${_('cos(step)')}:
${_('js')}:\t${cos_jsVal}
${_('wasm')}:\t${cos_asmVal}
${_('fp')}:\t${cos_fpVal}
${_('fpRaw')}:${cos_fpVal.rawValue}
${_('sqrt(step)')}:
${_('js')}:\t${sqrt_jsVal}
${_('wasm')}:\t${sqrt_asmVal}
${_('fp')}:\t${sqrt_fpVal}
${_('fpRaw')}:${sqrt_fpVal.rawValue}
${_('sin(step)*cos(step)*sqrt(step)')}:
${_('js')}:\t${sct_jsVal}
${_('wasm')}:\t${sct_asmVal}
${_('fp')}:\t${sct_fpVal}
${_('fpRaw')}:${sct_fpVal.rawValue}
`