我在使用谷歌云函数的谷歌Firestore中遇到了一些非常奇怪的减法行为。
这是我的测试谷歌功能代码:
exports.testCounter = functions.https.onCall((data, context) => {
db.collection('counter').doc('test').update({
count: admin.firestore.FieldValue.increment(-0.0005)
});
});
然后我从cli调用函数:
firebase functions:shell
testCounter({test: "demo"})
这是我创建的用于测试的文档:初始模式
然后,在第一次执行之后,一切都完全按照预期进行,数字5现在是4.9995首次执行后的文档
然而,在第二次执行后,4.9995不是预期的4.9990,而是变为4.9990000000000006。:第二次执行后的文档
有人知道怎么解决这个问题吗?或者这是意料之中的行为?
谢谢,祝你今天过得愉快!
Rick
这是使用IEEE 754标准的浮点数的标准行为,这也是Firestore所使用的。简而言之,计算机在有效存储浮点数据时会失去精度。
如果您不能接受这种行为,那么根本不应该存储浮点数字,而应该只存储整数。整数应包含浮点等效值通常需要的所有精度,但将浮点值乘以所需精度的情况除外。
例如,如果您需要三个小数点的精度(例如5.005(,请将浮点值乘以1000,去掉小数部分,然后存储整数5005。如果你需要加0.005,那么你应该加5。然后,您可以在客户端上以任何方式格式化该数字。
这实际上不是Firebase问题,只是浮点数固有的问题。
(4.9990000006).toFixed(4); // 4.9990
将toFixed
中的参数4
替换为所需的任何精度。
正如Doug所解释的,问题来自浮点数字的行为。
一种解决方案是在Cloud Function中使用big.js库。
它在云函数中运行良好(就像在任何Node.js代码中一样(,但这意味着您将无法再使用admin.firestore.FieldValue.increment()
。