2013-10-08 34 views
3

我们需要将可能类似于3.33333000540733337的计算值转换为3 1/3。我试过的任何库如https://github.com/peterolson/BigRational.js都会将其转换为最准确的有理数,而我只关心近似有理数,重要的小数.01。将浮点数转换为javascript中的近似分数

在ruby中,我们目前使用Rational(1.333).rationalize(Rational(0.01)),它给出了1作为整数,1作为分子,3作为分母。

对算法的任何想法可能会有所帮助。

+1

[ “如何浮子转换为人类可读的级分?”](HTTP:// stackoverflow.com/questions/95727/how-to-convert-floats-to-human-readable-fractions)和s特别是[这个面向JavaScript的答案](http://stackoverflow.com/a/681534/1934901) – tehsockz

+0

请记住,将'3.33333000540733337'转换为有理数“.01重要小数”将产生'3 33/100 ',而不是'3 1/3'。 –

+0

Peter yep,我们真的需要一个减少的近似分数。 – dstarh

回答

4

您可以使用https://github.com/peterolson/BigRational.js库使用这样的函数:

function rationalize(rational, epsilon) { 
    var denominator = 0; 
    var numerator; 
    var error; 

    do { 
     denominator++; 
     numerator = Math.round((rational.numerator * denominator)/rational.denominator); 
     error = Math.abs(rational.minus(numerator/denominator)); 
    } while (error > epsilon); 
    return bigRat(numerator, denominator); 
} 

它会返回一个bigRat对象。你可以检查你的例子:

console.log(rationalize(bigRat(3.33333000540733337),0.01)); 
+0

谢谢,这似乎可以做到这一点,我将不得不写一些比较测试,看看它是否符合我们从ruby中获得的结果。 – dstarh

+0

这只适用于JavaScript'Number'类型范围内的分子和分母,这可能或可能不够。如果您需要保留任意长度的分子和分母,您应该使用BigRat方法,例如'numerator = BigRat(rational.numerator.times(分母))。over(rational.denominator).round()'等等。 –

+0

@PeterOlson很有可能我们会处理的数量足够小,可以放在标准的厨房食谱中,所以我怀疑我们是否会处理数字处理的范围,至少在数字的左边十进制,并且假设我们试图在某种意义上使小数右边的数字不那么精确,我认为这应该是确定的。 – dstarh

1

你可以使用.toFixed()得到一个圆,固定精度版本,然后应用BigRational到:

var n = 3.33333000540733337; 
m = n.toFixed(2);  // 3.33 

另外,.toPrecision()会给一个数字的显著位数specificied数。

参考: .toFixed() .toPrecision()

-5

时间重温你的数学。这真是小学数学,但这有点容易被人遗忘。你为什么要3 1/3?

您试图将有理数(所有浮点数都是有理数)转换为另一个有理数(所有分数都是有理数)。

所以选择你的分母。一切都源于此! (减少到最低条款 - 除非你想看起来像你放弃了小学。)

+1

我们正在显示食谱数据和从3汤匙面粉转换成3 1/3杯面粉。换算系数都是以克为单位的,所以我们知道一个非常精确的数字,但需要一个更加近似的值。因此需要知道3 1/3而不是3.33333333334或类似 – dstarh

+0

您错过了这一点!为什么3/3(10/3)而不是3.25(13/4),3.5(7/2)或3.4(17/5)?或3.3(330/100降至33/10)? –

+1

,因为我们正在打印食谱,而且我们需要通用测量结果而不是“过于精确”的任何结果 – dstarh

0

我会再试一次。大概你把问题标记为“数学”。所以让我们看看数学。

  1. 分数是有理数。
  2. 有理数是n除以m(n/m)的所有形式,其中n和m是整数且m不为零。
  3. 你想要一个“混合分数”。
  4. 在决定分母(m)之前,您不能指望“舍入到最接近的分数”,全部或混合。如果你选择m = 100,那么你可以四舍五入到最接近的100。如果你选择1,那么你可以四舍五入到最接近的整数。 2到最近的一半,等等。
  5. 既然您已经选择了分母,那么我们称之为m,然后将您的值(v)乘以m。
  6. 将结果舍入为最接近的整数,称之为rv。
  7. 您的混合分数的整个部分将是floor(rv/m)。小数部分将是(rv模m)/ m (模意味着首先按秒除,剩余部分作为结果)

    示例v = 3.45。

    要将其舍入到最接近的1/3,所以M = 3

    RV =舍入到最近的整数(3.45 * 3)= ROUND(10.35)= 10

    整个部分=地板(10/3)= 3

    小数部分=(10模3)/ 3 = 1/3