如何在Javascript中模拟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)的结果相同?如果不是的话,我怎样才能做到这一点呢 上下文/我尝试过的

如果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
)的结果相同?如果不是的话,我怎样才能做到这一点呢

上下文/我尝试过的内容

在上下文中,这个问题是我试图解决的一个更大问题的一部分,我已经为此设置了这个问题

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运算的巨大计算,才能用累积的浮点噪声影响第五位有效数字。因此,尽管你必须注意,但我不会将其描述为“危险”。当然,在所有与合同有关的事项中,应使用完全反映合同中概述或暗示的条件和程序的方法。