javascript - TypeScript:我无法让浮点/十进制数学正常工作。(82.80000000000001,但应该是 82.8)
问题描述
问题:
我在 JavaScript/Typescript 中遇到小数/浮点数学问题。我知道有关这些问题的帖子,但我没有运气。
期望的结果:
82.8
结果:
82.80000000000001
什么工作:
total += (array[i] * weight[i] * 100) / 100;
行正常工作,但相同的逻辑不适用于total
.
我试过的:
- 在另一个函数中,我将值乘以 10 或 100。这可行,但我无法让它在我的情况下工作。
const remainder: number = ((1 - Math.sqrt(value)) * 10) / 10;
- 人们建议使用
toFixed(2);
,但这会将数字的类型转换为字符串,这是我不想要的。
计算加权平均.tsx:
// Calculate Weighted Average
export const calculateAverageWeighted = (array: Array<number>, weight: Array<number>) => {
// Check If Data Exists
if (array.length >= 1) {
// Weight Length: Must Equal Array Length
if (weight.length == array.length) {
// Weight Sum: Must Equal 1 Or 100
if (weight.reduce((total: number, value: number) => { return total + value }) === 1 || weight.reduce((total: number, value: number) => { return total + value }) === 100) {
// Total
let total: number = 0;
// Iterate Over Array
let i: number = 0;
while (i < array.length) {
// Add To Total
total += (array[i] * weight[i] * 100) / 100;
// Increase I
i++;
}
// IMPORTANT: FLOAT MATH (NOT WORKING HERE)
return (total * 100) / 100;
}
else {
// Error
throw new Error('Error: Values of Weight Array must be equal to 1 or 100 (calculateAverageWeighted)');
}
}
// Array Length Is Less Than Weight Length
else if (array.length < weight.length || array.length > weight.length) {
// Error
throw new Error('Error: Length of weight must be equal to input Array (calculateAverageWeighted)');
}
}
else {
// Error
throw new Error('Error: Empty Array (calculateAverageWeighted)');
}
};
解决方案
典型的浮点值是二元有理数,一些 n 位整数乘以 2 的幂,其中n
指数范围是有限的。
类似代码total += (array[i] * weight[i] * 100) / 100;
执行 2 乘法、除法和加法。每个乘积、商和总和可能与数学预期的结果不完全相同,因为结果被四舍五入并保存到最接近的二元有理数。
82.8 本身并不是完全可编码的。相反,最接近的值是
82.7999999999999971578290569595992565155029296875
82.8 // OP's hoped for result (not possible)
82.80000000000001136868377216160297393798828125 // Next best choice.
82.80000000000001 // OP's reported result
相反,接受结果与数学结果不完全相同,并将报告的结果限制为四舍五入的结果,可能是 14-15 位有效数字。
// 345678901234
82.800000000000 // 14 significant places
或者使用整数执行数学运算:将所有内容缩放 0.001。
或者使用十进制浮点数。(仍然 1.0/7.0 也不准确)
或使用基于精确的数学库执行。
或者接受 82.80000000000001足够简单。