提问人:Alexander Veheecke 提问时间:9/8/2022 最后编辑:E_net4Alexander Veheecke 更新时间:9/10/2022 访问量:36
JavaScript 浮点数未正确截断
JavaScript float not truncating correctly
问:
我正在努力让浮点数正确显示。它在大多数情况下都有效。例如,如果我在“kWh”中输入 0.2,在“使用小时数”中输入 0.04,则在“总计”中输出 0.008。但是,当我将这些值更改为 0.02 和 0.23 时,它会输出 0.0460000000000000006。为什么不输出 0.046?我在这里错过了什么?
<script>
function calculate(){
var amount = document.getElementById("kW").value;
var amount = parseFloat(amount).toFixed(2);
var quantity = document.getElementById("hours").value;
var quantity = parseFloat(quantity).toFixed(2);
var total = amount * quantity;
document.getElementById("total").value = total;
}
</script>
<div class="kWattsCol">
<p><b>kWh</b></p>
<input type="number" oninput="calculate()" id="kW" required>
</div>
<div class="hoursCol">
<p><b>Hours used</b></p>
<input type="number" oninput="calculate()" id="hours"required>
</div>
<div class="totalCol">
<p><b>Total</b></p>
<input type="text" id="total" readonly>
</div>
答:
校正
...当我将这些值更改为 0.02 和 0.23 时,它输出 0.0460000000000000006...
这些浮点积将是接近 .0046 的数字,而不是接近 .046 的数字。所以我怀疑实际输入是“0.2”和“0.23”。下面的答案就是在此基础上进行的。
讨论
当使用默认的数字 JavaScript 格式时,它会生成足够多的有效数字,以便以浮点格式唯一区分浮点数与其相邻数。这个答案进一步描述了这一点。
当输入“0.2”转换为 JavaScript 使用的浮点格式(IEEE-754 binary64,也称为“双精度”)时,结果为 0.2000000000000000011102230246251565404236316680908203125。转换“0.04”时,结果为0.040000000000000000832667268468867405317723751068115234375。当这些相乘时,结果为 0.0080000000000000000166533453693773481063544750213623046875。(这包括将实数算术乘积舍入到以浮点格式表示的最接近的值。
以下是结果前的邻居、结果和结果后的邻居:
0.00799999999999999843180997771696638665162026882171630859375 0.008000000000000000166533453693773481063544750213623046875 0.00800000000000000190125692967058057547546923160552978515625
观察到 .008 最接近其中的中间,即算术结果。这意味着,当 0.0080000000000000000166533453693773481063544750213623046875 被格式化为显示时,我们只需要生成“0.008”来识别它。
在第二种情况下,转换“0.23”得到 0.230000000000000000099920072216264088638126850128173828125,则乘积为 0.0460000000000000006161737786669618799351155757904052734375。
看看之前的邻居、结果和之后的邻居,我们有:
0.04599999999999999922284388276239042170345783233642578125 0.046000000000000006161737786669618799351155757904052734375 0.0460000000000000131006316905768471769988536834716796875
观察到 .046 更接近之前的邻居,而不是结果;它在小数点后第十九位相差不到 1,而结果相差超过 6。因此,为了确定结果,我们需要生成“0.0460000000000000006”。
评论