javascript 将十进制数转换为javascript中的分数或最接近的分数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23575218/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 01:08:08  来源:igfitidea点击:

convert decimal number to fraction in javascript or closest fraction

javascript

提问by Muhammad Umer

So i want to be able to convert any decimal number into fraction. In both forms such as one without remainder like this: 3/5or with remainder: 3 1/4.

所以我希望能够将任何十进制数转换为分数。在两种形式中,例如像这样没有余数的一个:3/5或有余数:3 1/4

what i was doing is this..

我在做的是这个..

lets say i have number .3435.

假设我有号码 0.3435。

  • Calculate amount of digits after decimals.
  • multiply by 10 with power of the amount before number.
  • then somehowfind greatest common factor.
  • 计算小数点后的位数。
  • 乘以 10 乘以数字之前的数量的幂。
  • 然后以某种方式找到最大公因数。

Now i don't know how to find GCF. And nor i know how to implement logic to find fraction that represents a number closely or in remainder form if exact fraction doesn't exists.

现在我不知道如何找到 GCF。而且我也不知道如何实现逻辑来找到表示一个数字的分数,如果确切分数不存在,则该分数或以余数形式表示。

code i have so far: (testing)

我到目前为止的代码:(测试)

x = 34/35;
a = x - x.toFixed();
tens = (10).pow(a.toString().length - 2);

numerator = tens * x;
denominator = tens;

回答by Sani Singh Huttunen

Your first 2 steps are reasonable.

您的前两个步骤是合理的。

But what you should do is for the numerator and denominator calculate the Greatest Common Divisor (GCD)and then divide the numerator and denominator with that divisor to get the fraction you want.

但是您应该做的是为分子和分母计算最大公约数(GCD),然后将分子和分母与该除数相除以获得您想要的分数。

GCD is rather easy to calculate. Here is Euclid's algorithm:

GCD 相当容易计算。这是欧几里德的算法

var gcd = function(a, b) {
  if (!b) return a;

  return gcd(b, a % b);
};

Edit

编辑

I've added a fully working JSFiddle.

我添加了一个完全可用的 JSFiddle

回答by Stephen Quan

You can use brute force test on different denominators and retain the result that has least error.

您可以对不同的分母使用蛮力测试并保留误差最小的结果。

The algorithm below is an example of how you might go about this, but, suffers from being inefficient and limited to searching for denominators up to 10000.

下面的算法是一个示例,说明如何进行此操作,但是效率低下且仅限于搜索最多 10000 的分母。

function find_rational( value, maxdenom ) {
  console.clear();
  console.log( "Looking up: " + value );
  let best = { numerator: 1, denominator: 1, error: Math.abs(value - 1) }
  if ( !maxdenom ) maxdenom = 10000;
  for ( let denominator = 1; best.error > 0 && denominator <= maxdenom; denominator++ ) {
    let numerator = Math.round( value * denominator );
    let error = Math.abs( value - numerator / denominator );
    if ( error >= best.error ) continue;
    best.numerator = numerator;
    best.denominator = denominator;
    best.error = error;
    console.log( "Intermediate result: "
                   + best.numerator + "/" + best.denominator
                   + " (" + ( best.numerator/best.denominator)
                   + " error " + best.error + " )" );
  }
  console.log( "Final result: " + JSON.stringify( best ) );
  return best;
}
  
function calc() {
    const value = parseFloat( $("#myInput").val() );
    if ( isNaN(value) ) {
        $( "#myResult" ).val( "NaN" );
        return;
    }
    const rational = find_rational( value, 10000 );
    $("#myResult").val( rational.numerator
                        + " / " + rational.denominator
                        + " ( Error: " + rational.error + " )" );
}

calc();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<P>
Enter a decimal number:<BR/>
<INPUT type="text" name="myInput" id="myInput" value=".3435" onkeyup="calc()"/><BR/>
</P>

<P>
Resulting Rational:<BR/>
<INPUT name="myResult" id="myResult" value=""/><BR/>
</P>

The above determines the .3435 as a fraction is 687 / 2000.

以上确定 0.3435 作为一个分数是 687 / 2000。

Also, had you gave it PI (e.g. 3.1415926) it produces good looking fractions like 22/7 and 355/113.

此外,如果你给它 PI(例如 3.1415926),它会产生漂亮的分数,如 22/7 和 355/113。

回答by Xotic750

Unless you are willing to work on developing something yourself then I would suggest using a library that someone has already put effort into, like fraction.js

除非你愿意自己开发一些东西,否则我建议使用一个已经有人努力开发的库,比如fraction.js

Javascript

Javascript

var frac = new Fraction(0.3435);

console.log(frac.toString());

Output

输出

687/2000

On jsFiddle

jsFiddle 上

回答by chowey

I get very poor results using the GCD approach. I got much better results using an iterative approach.

使用 GCD 方法我得到的结果很差。我使用迭代方法得到了更好的结果。

For example, here is a very crude approach that zeros in on a fraction from a decimal:

例如,这是一个非常粗略的方法,它对小数的一个分数进行归零:

function toFraction(x, tolerance) {
    if (x == 0) return [0, 1];
    if (x < 0) x = -x;
    if (!tolerance) tolerance = 0.0001;
    var num = 1, den = 1;

    function iterate() {
        var R = num/den;
        if (Math.abs((R-x)/x) < tolerance) return;

        if (R < x) num++;
        else den++;
        iterate();
    }

    iterate();
    return [num, den];
}

The idea is you increment the numerator if you are below the value, and increment the denominator if you are above the value.

这个想法是,如果低于该值,则增加分子,如果高于该值,则增加分母。

回答by rman

One quick and easy way of doing it is

一种快速简便的方法是

getFraction = (decimal) => {
  for(var denominator = 1; (decimal * denominator) % 1 !== 0; denominator++);
  return {numerator: decimal * denominator, denominator: denominator};
}

回答by Dehan de Croos

Use the Euclidean algorithmto find the greatest common divisor.

使用欧几里得算法找到最大公约数。

function reduce(numerator,denominator){
  var gcd = function gcd(a,b){
    return b ? gcd(b, a%b) : a;
  };
  gcd = gcd(numerator,denominator);
  return [numerator/gcd, denominator/gcd];
}

This will provide you with the following results on your console

这将在您的控制台上为您提供以下结果

reduce(2,4);
// [1,2]

reduce(13427,3413358);
// [463,117702]

So by continuing from already what you have,

所以通过继续你已经拥有的,

var x = 34/35;
var a = x - x.toFixed();
var tens = Math.pow(10,a.toString().length - 2);

var numerator = tens * x;
var denominator = tens;

reduce(numerator,denominator);

Source: https://stackoverflow.com/a/4652513/1998725

来源:https: //stackoverflow.com/a/4652513/1998725

回答by kennebec

The tricky bit is not letting floating points get carried away.

棘手的一点是不要让浮点被带走。

Converting a number to a string restrains the trailing digits,

将数字转换为字符串会限制尾随数字,

especially when you have a decimal with an integer, like 1.0625.

特别是当你有一个带整数的小数时,比如 1.0625。

You can round off clumsy fractions, by passing a precisionparameter.

您可以通过传递一个precision参数来对笨拙的分数进行四舍五入。

Often you want to force a rounded value up, so a third parameter can specify that.

通常您想强制向上取整的值,因此第三个参数可以指定。

(e.g.; If you are using a precision of 1/64, the smallest return for a non-zero number will be 1/64, and not 0.)

(例如;如果您使用 1/64 的精度,则非零数的最小返回值为 1/64,而不是 0。)

Math.gcd= function(a, b){
    if(b) return Math.gcd(b, a%b);
    return Math.abs(a);
}
Math.fraction= function(n, prec, up){
    var s= String(n), 
    p= s.indexOf('.');
    if(p== -1) return s;

    var i= Math.floor(n) || '', 
    dec= s.substring(p), 
    m= prec || Math.pow(10, dec.length-1), 
    num= up=== 1? Math.ceil(dec*m): Math.round(dec*m), 
    den= m, 
    g= Math.gcd(num, den);

    if(den/g==1) return String(i+(num/g));

    if(i) i= i+' and  ';
    return i+ String(num/g)+'/'+String(den/g);
}

Math.roundFraction(.3435,64); value: (String) 11/32

Math.roundFraction(.3435,64); 值:(字符串)11/32

回答by Carter Swinney

I had researched all over the website and I did combine all code into one, Here you go!

我已经研究了整个网站,我确实将所有代码合二为一,你去吧!

function fra_to_dec(num){
    var test=(String(num).split('.')[1] || []).length;
    var num=(num*(10**Number(test)))
    var den=(10**Number(test))
    function reduce(numerator,denominator){
        var gcd = function gcd(a,b) {
            return b ? gcd(b, a%b) : a;
        };
        gcd = gcd(numerator,denominator);
        return [numerator/gcd, denominator/gcd];
    }
    return (reduce(num,den)[0]+"/"+reduce(num,den)[1])
}

This code is very easy to use! You can even put numberin this function!

这段代码非常好用!你甚至可以把在此功能!

回答by Jeff Price

I came up with this for 16ths

我想出了这个 16ths

function getfract(theNum){
    var input=theNum.toString();
    var whole = input.split(".")[0];
    var rem = input.split(".")[1] * .1;
    return(whole + " " + Math.round(rem * 16) + "/16");
}