1.1+2.2 > 3.3
代码:
if (sumAllocateTotal.value > capitalInfoStore.currentSelectedCapitalInfo.capitalValidTotal) {
ElMessage.warning("合计的指标分配金额不能大于指标可用总额");
return;
}

在 Vue 3(以及所有使用 JavaScript 的环境)中,1.1 + 2.2 > 3.3 的结果为 true,这并不是 Vue 特有的问题,而是 JavaScript 浮点数精度导致的经典现象。
为什么会出现这种情况?
JavaScript 中的数字采用 IEEE 754 双精度 64 位二进制浮点数 标准。这意味着像 1.1、2.2、3.3 这样的十进制小数,在转换为二进制时可能是无限循环的,无法被精确表示。因此,实际存储的是近似值。
具体计算过程
-
1.1 在内存中实际表示为:1.100000000000000088817841970012523233890533447265625
-
2.2 实际表示为:2.20000000000000017763568394002504646778106689453125
-
两者相加得到近似值:3.300000000000000266453525910037569701671600341796875
-
而 3.3 的实际存储值是:3.29999999999999982236431605997495353221893310546875
很明显,1.1 + 2.2 的结果略大于 3.3,因此 1.1 + 2.2 > 3.3 成立。
在 Vue 3 中如何正确处理这种比较?
如果你在 Vue 的模板或逻辑中需要比较浮点数,不要直接使用 == 或 >,而应该引入一个很小的误差范围(称为“机器精度”)。
示例:使用计算属性进行安全比较
vue
<template>
<div>
<p>1.1 + 2.2 = {{ sum }}</p>
<p>是否大于 3.3?{{ isGreater }}</p>
<p>是否约等于 3.3?{{ isApproxEqual }}</p>
</div>
</template>
<script setup>
import { ref, computed } from 'vue'
const EPSILON = 1e-10; // 根据精度需求调整
const sum = ref(1.1 + 2.2);
const target = 3.3;
const isGreater = computed(() => sum.value > target); // 仍然会得到 true
const isApproxEqual = computed(() => Math.abs(sum.value – target) < EPSILON); // 推荐做法
</script>
通用比较函数
javascript
function nearlyEqual(a, b, epsilon = 1e-10) {
return Math.abs(a – b) < epsilon;
}
在模板中直接使用过滤器或方法
你可以将比较逻辑封装在方法中,在模板里调用:
vue
<template>
<p>{{ isGreaterThan(1.1+2.2, 3.3) }}</p>
</template>
<script setup>
const isGreaterThan = (a, b, epsilon = 1e-10) => {
return a – b > epsilon; // 如果希望严格大于且考虑误差
};
</script>
总结
-
根本原因是 IEEE 754 浮点数精度限制,与 Vue 无关。
-
解决方案:永远不要直接比较浮点数是否相等或大小,而是引入一个极小的容差值(epsilon)。
-
Vue 的响应式系统不会改变 JavaScript 数字的行为,但在模板和逻辑中你需要自己处理精度问题。
如果你遇到类似的比较,请始终使用 Math.abs(a – b) < epsilon 来判断“相等”,或使用带容差的大小判断。
修改后的代码:
// 永远不要直接比较浮点数是否相等或大小,而是引入一个极小的容差值(epsilon)
// 请始终使用 Math.abs(a – b) < epsilon 检查"两个数是否明显不相等",a – b > epsilon 检查"a是否明显大于b"。
const epsilon = 1e-10;
if (sumAllocateTotal.value – capitalInfoStore.currentSelectedCapitalInfo.capitalValidTotal > epsilon) {
ElMessage.warning("合计的指标分配金额不能大于指标可用总额");
return;
}
应用效果:







