如何在Javascript中模拟Google工作表乘法公式的结果?
如果Google工作表中的如何在Javascript中模拟Google工作表乘法公式的结果?,javascript,math,google-sheets,decimal,multiplication,Javascript,Math,Google Sheets,Decimal,Multiplication,如果Google工作表中的f5单元格的值是1.1000(一个格式为4位小数的数字),而f6的值是=f5*1.073,我如何确保在Javascript中乘以这些值得到相同的结果,例如: var original_value = 1.1000; var derivative_value = original_value * 1.073; 具体来说,我的问题是-Javascript乘法(导数_值)的结果是否与Google公式(f6)的结果相同?如果不是的话,我怎样才能做到这一点呢 上下文/我尝试过的
f5
单元格的值是1.1000
(一个格式为4位小数的数字),而f6
的值是=f5*1.073
,我如何确保在Javascript中乘以这些值得到相同的结果,例如:
var original_value = 1.1000;
var derivative_value = original_value * 1.073;
具体来说,我的问题是-Javascript乘法(导数_值
)的结果是否与Google公式(f6
)的结果相同?如果不是的话,我怎样才能做到这一点呢
上下文/我尝试过的内容
在上下文中,这个问题是我试图解决的一个更大问题的一部分,我已经为此设置了这个问题
JSFIDLE有一个用于原始值的输入和一个用于乘数的输入
它将结果输出到小数点后四位,并在需要时添加尾随的零(这是结果所需的格式)
这是为了检查我正在编写的Javascript代码是否会产生与GoogleSheet公式相同的结果
[JSFIDLE已经更新,还可以将decimal.js
结果记录到控制台进行比较]
编辑
有一个建议可以使用,但我不确定它将如何应用-类似于以下内容
var original_value = new Decimal(1.1000);
// some different multipliers for testing
var multiplier_a = new Decimal(1.073);
var multiplier_b = new Decimal(1.1);
// some different results for testing
var derivative_value_a = original_value.times(multiplier_a).toString();
var derivative_value_b = original_value.times(multiplier_b).toString();
console.log(derivative_value_a); // 1.1803
console.log(derivative_value_b); // 1.21
这比普通Javascript原始值*乘数更准确吗?更重要的是,对于这个问题,它是否总是模拟谷歌表单公式产生的相同结果 JavaScript使用所谓的双精度浮点格式(64位)——
Google Sheets似乎使用相同的格式,您可以通过=f6*1E13-round(f6*1E13)
对其进行测试,以查看f6不是以固定数字格式存储的,而是格式化的
请参见如何在Javascript中格式化数字
要生成一些测试数据,请执行以下操作:
[…数组(10)].forEach(()=>{
常数f5=1.1
常数x=Math.random()/100
常数f6=f5*x
控制台日志(x,f6.toFixed(4))
})
再次访问后,我更新了
我认为令人满意的解决方案的主要组成部分是:
- 将
原始值
和乘数
转换为对象
- 使用
decimal.js
方法进行乘法运算
- 使用
decimal.js
方法进行舍入
- 使用参数值
(4,7)
定义四位小数,并使用四舍五入
四舍五入,相当于数学.ROUND
()
例如:
var my_decimal_js_value = new Decimal(original_value).times(new Decimal(multiplier)).toDecimalPlaces(4, 7);
为了向结果中添加任何必要的尾随零,我使用:
function trailingZeros(my_decimal_js_value) {
var result = my_decimal_js_value;
// add zeros if required:
var split_result = result.toString().split(".");
// if there are decimals present
if (split_result[1] != undefined) {
// declare trailing_zeros;
var trailing_zeros;
// get the amount of decimal numbers
decimals_present = split_result[1].length;
// if one decimal number, add three trailing zeros
if (decimals_present === 1) {
trailing_zeros = "000";
result += trailing_zeros;
}
// if two decimal numbers, add two trailing zeros
else if (decimals_present === 2) {
trailing_zeros = "00";
result += trailing_zeros;
}
// if three decimal numbers, add one trailing zero
else if (decimals_present === 3) {
trailing_zeros = "0";
result += trailing_zeros;
}
// if four decimal numbers, just convert result to string
else if (decimals_present === 4) {
result = result.toString();
}
}
// if there are no decimals present, add a decimal place and four zeros
else if (split_result[1] === undefined) {
trailing_zeros = ".0000";
result += trailing_zeros;
}
return result;
}
我仍然不能绝对肯定这是否模仿了Google Sheet乘法公式,但是,基于以下内容,使用或另一个专用的十进制库似乎是优于普通JavaScript的首选方法(以避免可能的舍入错误):
Javascript可能是一种危险的语言,因为它存在舍入错误,因此需要进行大量计算。如果你想安全起见,可以使用一个数学库,比如:?据我所知,我仍然需要知道Google Sheet对乘法的“使用”是什么,这样我就可以复制相同的行为。我在问题中添加了使用decimal.js的尝试。我还更新了原始的JSFIDLE,将decimal.js
结果记录到控制台进行比较。@EmilS.Jørgensen据我所知,js和Google工作表都使用相同的float64数字格式-您对Google工作表有什么不同的规范吗???@user1063287请不要忘记=f5*1.073与=圆形(f5,4)*1.073不同@埃米尔斯·约根森:除了灾难性的相消之外,你还需要大约1e11运算的巨大计算,才能用累积的浮点噪声影响第五位有效数字。因此,尽管你必须注意,但我不会将其描述为“危险”。当然,在所有与合同有关的事项中,应使用完全反映合同中概述或暗示的条件和程序的方法。