欢迎光临
我们一直在努力

Vue3项目中解决1.1+2.2 > 3.3的问题

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;
}

应用效果:

赞(0)
未经允许不得转载:171主机测评 » Vue3项目中解决1.1+2.2 > 3.3的问题
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址