首页 > 解决方案 > Javascript(浮点问题):有没有可靠的方法将分数转换为小数然后再返回?

问题描述

假设我有一个非常简单的分数(为了这个问题的目的,假设所有讨论的情况都是0 < [VALUE] < 1; 也就是说:没有类似8 7/16or 1.625

我的起始分数:

someFraction = '1/3'; // result: STRING value containing "1/3".

可以很容易地将其转换为小数:

correspondingDecimal = eval(someFraction); // result: FLOAT value containing 0.3333333333333333

(是的,是的,“邪恶之类的eval。在这里和我一起工作;这是一个例子)

现在说我希望它再次返回到"1/3". 如果是这样1/4 (0.25),没问题:

我们想要一个简单的最大公分母函数(将结果降低到可管理性),比如说

function reduce(numerator,denominator){ 
    let getGCD = (a,b) => b ? getGCD(b, a%b) : a; 
    gcd = getGCD(numerator,denominator); 
    return (numerator/gcd) + '/' + (denominator/gcd); 
}

...然后我们就可以取出测试字符串的小数部分:

let justDecimalPart = ('' + 0.25).slice(2);

并乘以它的长度幂以使我们的分子和分母减少:

let commonFactor = Math.pow(10,justDecimalPart.length); // Result: 100
//                     = 25                 = 100
reduce((justDecimalPart * commonFactor), commonFactor); // Result: 1/4

... 首都!结果很好!

编辑:一时兴起,我在十进制值上尝试了相同的 reduce 函数,根本没有将它们相乘(reduce(0.25,1); // result: "1/4")。对不起; 放屁。忽略上面的指数位☺️

...但是1/3是一个重复的小数。如果我们执行相同的步骤,我们将得到3333333333333333/10000000000000000( ((1/3) * 1e16) + '/' + 1e16)。像17/29.

有什么办法可以在跳槽"1/3"后返回1/3

编辑:我不想达到无限的精度,只是想达到一个可管理的精度,最好是通过节流/限制小数长度然后舍入/简化结果。

此处的用例示例:我正在研究木工计算器。25 毫米,以美国通用单位表示(精确到小数点后 3 位)与 63/64 相同。我似乎只能到达 125/128。

(25/25.4).toPrecision(3) = 0.984
(63/64).toPrecision(3) = 0.984

标签: javascriptmathfloating-pointdata-conversionfractions

解决方案


看来我在转变过程中遗漏了一步;我没有将小数乘以分母的结果四舍五入:

decimalValue = (63 / 64).toPrecision(3); // Result: 0.984
denominator = 128; 
numerator = decimalValue * denominator; // Result: 125.952
numerator = Math.round(numerator); // Result: 126
reduce(numerator, denominator); // Result: 63/64

推荐阅读