JavaScriptで、10進数(_0.0002
_など)を文字列( "_2/10000"
_など)として表される小数に変換する方法はありますか?
decimalToFraction
と呼ばれる関数がこの目的で作成されていた場合、decimalToFraction(0.0002)
は文字列_"2/10000"
_を返します。
Erik Garrisonの fraction.js ライブラリを使用して、それを実行し、より小数の演算を行うことができます。
var f = new Fraction(2, 10000);
console.log(f.numerator + '/' + f.denominator);
.003を行うには、あなたはただ行うことができます
var f = new Fraction(.003);
console.log(f.numerator + '/' + f.denominator);
少し 「小数から小数js」という用語でグーグルする 最初の結果はこれでした:
http://wildreason.com/wildreason-blog/2010/javascript-convert-a-decimal-into-a-simplified-fraction/
それはうまくいくようです:
function HCF(u, v) {
var U = u, V = v
while (true) {
if (!(U%=V)) return V
if (!(V%=U)) return U
}
}
//convert a decimal into a fraction
function fraction(decimal){
if(!decimal){
decimal=this;
}
whole = String(decimal).split('.')[0];
decimal = parseFloat("."+String(decimal).split('.')[1]);
num = "1";
for(z=0; z<String(decimal).length-2; z++){
num += "0";
}
decimal = decimal*num;
num = parseInt(num);
for(z=2; z<decimal+1; z++){
if(decimal%z==0 && num%z==0){
decimal = decimal/z;
num = num/z;
z=2;
}
}
//if format of fraction is xx/xxx
if (decimal.toString().length == 2 &&
num.toString().length == 3) {
//reduce by removing trailing 0's
decimal = Math.round(Math.round(decimal)/10);
num = Math.round(Math.round(num)/10);
}
//if format of fraction is xx/xx
else if (decimal.toString().length == 2 &&
num.toString().length == 2) {
decimal = Math.round(decimal/10);
num = Math.round(num/10);
}
//get highest common factor to simplify
var t = HCF(decimal, num);
//return the fraction after simplifying it
return ((whole==0)?"" : whole+" ")+decimal/t+"/"+num/t;
}
// Test it
alert(fraction(0.0002)); // "1/5000"
私はこのサイト http://mathforum.org/library/drmath/view/51886.html を使用して関数を作成しましたが、この記事で言及しているように、部首やpiには無理な数の数値が表示されます。
それが役に立てば幸いです。
function Fraction(){}
Fraction.prototype.convert = function(x, improper)
{
improper = improper || false;
var abs = Math.abs(x);
this.sign = x/abs;
x = abs;
var stack = 0;
this.whole = !improper ? Math.floor(x) : 0;
var fractional = !improper ? x-this.whole : abs;
/*recursive function that transforms the fraction*/
function recurs(x){
stack++;
var intgr = Math.floor(x); //get the integer part of the number
var dec = (x - intgr); //get the decimal part of the number
if(dec < 0.0019 || stack > 20) return [intgr,1]; //return the last integer you divided by
var num = recurs(1/dec); //call the function again with the inverted decimal part
return[intgr*num[0]+num[1],num[0]]
}
var t = recurs(fractional);
this.numerator = t[0];
this.denominator = t[1];
}
Fraction.prototype.toString = function()
{
var l = this.sign.toString().length;
var sign = l === 2 ? '-' : '';
var whole = this.whole !== 0 ? this.sign*this.whole+' ': sign;
return whole+this.numerator+'/'+this.denominator;
}
//var frac = new Fraction()
//frac.convert(2.56, false)
//console.log(frac.toString())
//use frac.convert(2.56,true) to get it as an improper fraction
分子と分母のみを返す自己完結型の関数が必要な場合は、以下の関数を使用します。
var toFraction = function (dec) {
var is_neg = dec < 0;
dec = Math.abs(dec);
var done = false;
//you can adjust the epsilon to a larger number if you don't need very high precision
var n1 = 0, d1 = 1, n2 = 1, d2 = 0, n = 0, q = dec, epsilon = 1e-13;
while (!done) {
n++;
if (n > 10000) {
done = true;
}
var a = parseInt(q);
var num = n1 + a * n2;
var den = d1 + a * d2;
var e = (q - a);
if (e < epsilon) {
done = true;
}
q = 1 / e;
n1 = n2;
d1 = d2;
n2 = num;
d2 = den;
if (Math.abs(num / den - dec) < epsilon || n > 30) {
done = true;
}
}
return [is_neg ? -num : num, den];
};
//Usage:
//var frac = toFraction(0.5);
//console.log(frac)
//Output: [ 1, 2 ]
非常に古い質問ですが、多分誰かがこれが役に立つと思うかもしれません。それは反復的であり、再帰的ではなく、因数分解を必要としません
function getClosestFraction(value, tol) {
var original_value = value;
var iteration = 0;
var denominator=1, last_d = 0, numerator;
while (iteration < 20) {
value = 1 / (value - Math.floor(value))
var _d = denominator;
denominator = Math.floor(denominator * value + last_d);
last_d = _d;
numerator = Math.ceil(original_value * denominator)
if (Math.abs(numerator/denominator - original_value) < tol)
break;
iteration++;
}
return {numerator: numerator, denominator: denominator};
};
数値の文字列表現を使用する非常に簡単な解決策があります
string = function(f){ // returns string representation of an object or number
return f+"";
}
fPart = function(f){ // returns the fraction part (the part after the '.') of a number
str = string(f);
return str.indexOf(".")<0?"0":str.substring(str.indexOf(".") + 1);
}
wPart = function(f){ // returns the integer part (the part before the '.') of a number
str = string(f);
return str.indexOf(".")<0?str:str.substring(0, str.indexOf(".")); // possibility 1
//return string(f - parseInt(fPart(f))); // just substract the fPart
}
power = function(base, exp){
var tmp = base;
while(exp>1){
base*=tmp;
--exp;
}
return base;
}
getFraction = function(f){ // the function
var denominator = power(10, fPart(f).length), numerator = parseInt(fPart(f)) + parseInt(wPart(f))*denominator;
return "[ " + numerator + ", " + denominator + "]";
}
console.log(getFraction(987.23));
これは、分数に含まれる数値の数をチェックし、fが整数になるまでf/1の分数を拡張するだけです。これにより、分数が膨大になる可能性があるため、分子と分母の両方を両方の最大公約数で除算することで、分数を減らすことができます。
// greatest common divisor brute force
gcd = function(x,y){
for(var i = Math.min(x, y);i>0;i--) if(!(x%i||y%i)) return i;
return 1;
}
ありがたいことに、それは可能ですが、コードに変換する必要があります。
まったく理由もなく2.56でいきましょう。
数値の小数部分.56を使用します
.56には2桁あり、.56は56/100と記述します。
したがって、2 + 56/100であり、分子と分母の両方を 最大公約数 (この場合は4)で除算して、この分数を最低項に減らす必要があります。
したがって、この割合は最低条件に削減され、2 + 14/25になります。
それらの2全体を追加するには、除数を掛けて14に追加します
(2 * 25 + 14)/ 25 =64/25
これは少し古いかもしれませんが、投稿されたコードは0の値で失敗します私はそのエラーを修正し、以下の更新されたコードを投稿します
//function to get highest common factor of two numbers (a fraction)
function HCF(u, v) {
var U = u, V = v
while (true) {
if (!(U%=V)) return V
if (!(V%=U)) return U
}
}
//convert a decimal into a fraction
function fraction(decimal){
if(!decimal){
decimal=this;
}
whole = String(decimal).split('.')[0];
decimal = parseFloat("."+String(decimal).split('.')[1]);
num = "1";
for(z=0; z<String(decimal).length-2; z++){
num += "0";
}
decimal = decimal*num;
num = parseInt(num);
for(z=2; z<decimal+1; z++){
if(decimal%z==0 && num%z==0){
decimal = decimal/z;
num = num/z;
z=2;
}
}
//if format of fraction is xx/xxx
if (decimal.toString().length == 2 &&
num.toString().length == 3) {
//reduce by removing trailing 0's
// '
decimal = Math.round(Math.round(decimal)/10);
num = Math.round(Math.round(num)/10);
}
//if format of fraction is xx/xx
else if (decimal.toString().length == 2 &&
num.toString().length == 2) {
decimal = Math.round(decimal/10);
num = Math.round(num/10);
}
//get highest common factor to simplify
var t = HCF(decimal, num);
//return the fraction after simplifying it
if(isNaN(whole) === true)
{
whole = "0";
}
if(isNaN(decimal) === true)
{
return ((whole==0)?"0" : whole);
}
else
{
return ((whole==0)?"0 " : whole+" ")+decimal/t+"/"+num/t;
}
}
これは古い質問であることは知っていますが、大幅に簡略化された関数を作成しました。
_Math.fraction=function(x){
return x?+x?x.toString().includes(".")?x.toString().replace(".","")/(function(a,b){return b?arguments.callee(b,a%b):a;})(x.toString().replace(".",""),"1"+"0".repeat(x.toString().split(".")[1].length))+"/"+("1"+"0".repeat(x.toString().split(".")[1].length))/(function(a,b){return b?arguments.callee(b,a%b):a;})(x.toString().replace(".",""),"1"+"0".repeat(x.toString().split(".")[1].length)):x+"/1":NaN:void 0;
}
_
Math.fraction(2.56)
で呼び出す
そうなる:
string
を返す(分子と分母を含む配列にはMath.fraction(2.56).split("/")
を使用)これは非推奨の_arguments.callee
_を使用しているため、一部のブラウザでは互換性がない場合があることに注意してください。
テストする ここ
このようなことを試しましたか?
<script type="texrt/javascript>
var cnum = 3.5,deno = 10000,neww;
neww = cnum * deno;
while(!(neww % 2 > 0) && !(deno % 2 > 0)){
neww = neww / 2;
deno = deno / 2;
}
while(!(neww % 3 > 0) && !(deno % 3 > 0)){
neww = neww / 3;
deno = deno / 3;
}
while(!(neww % 5 > 0) && !(deno % 5 > 0)){
neww = neww / 5;
deno = deno / 5;
}
while(!(neww % 7 > 0) && !(deno % 7 > 0)){
neww = neww / 7;
deno = deno / 7;
}
while(!(neww % 11 > 0) && !(deno % 11 > 0)){
neww = neww / 11;
deno = deno / 11;
}
while(!(neww % 13 > 0) && !(deno % 13 > 0)){
neww = neww / 13;
deno = deno / 13;
}
while(!(neww % 17 > 0) && !(deno % 17 > 0)){
neww = neww / 17;
deno = deno / 17;
}
while(!(neww % 19 > 0) && !(deno % 19 > 0)){
neww = neww / 19;
deno = deno / 19;
}
console.log(neww+"/"+deno);
</script>
10進数を分数に変換およびを減らす分数を見つけた1つの代替を残します。これはJSライブラリです。
ライブラリは fraction.js を呼び出します。これは私にとって非常に役立ち、時間と労力を大幅に節約してくれました。他の誰かに役立つことを願っています!
私はpopnoodlesが提案したことをしました、そしてここにあります
function FractionFormatter(value) {
if (value == undefined || value == null || isNaN(value))
return "";
function _FractionFormatterHighestCommonFactor(u, v) {
var U = u, V = v
while (true) {
if (!(U %= V)) return V
if (!(V %= U)) return U
}
}
var parts = value.toString().split('.');
if (parts.length == 1)
return parts;
else if (parts.length == 2) {
var wholeNum = parts[0];
var decimal = parts[1];
var denom = Math.pow(10, decimal.length);
var factor = _FractionFormatterHighestCommonFactor(decimal, denom)
return (wholeNum == '0' ? '' : (wholeNum + " ")) + (decimal / factor) + '/' + (denom / factor);
} else {
return "";
}
}