分数の表示

分数表示をするには、分母と分子の最大公約数での約分が必要です。ユークリッド互除法という古くからある解法を用いることで、javascript で分数の表示を実装することができます。今のところ、係数入力には整数しか対応していません。

以下、参照  JavaScript 第6版 より

function memoize(f) {
  var cache = {};
  return function() {
    var key = arguments.length + Array.prototype.join.call(arguments,",");
    if (key in cache) return cache[key];
    else return cache[key] = f.apply(this, arguments);
  };
}
function gcd(m,n) {
  var t;
  if (m < n) t=n, n=m, m=t;
  while(n != 0) t=n, n = m%n, m=t;
    return m;
}
function output() {
  var gcdmemo = memoize(gcd);
  var a1= document.getElementById('a').value;
  var b1= document.getElementById('b').value;
  var c1= document.getElementById('c').value;
  var d1= document.getElementById('d').value;
  var p1= document.getElementById('p').value;
  var q1= document.getElementById('q').value;
  var x1= d1*p1-b1*q1, y1 = a1*q1-c1*p1;
  var z = a1*d1-b1*c1, z1 = Math.abs(z);
  if(z1 == 0) {
    document.getElementById('x').innerHTML = "x = " + a1 + 
        "x + " + b1 + "y = " + p1 + " のすべての解です。";
    document.getElementById('y').innerHTML = "y = " + a1 + 
        "x + " + b1 + "y = " + p1 + " のすべての解です。";
    return false;
  }
  if(Math.abs(gcdmemo(x1,z1)) == z1) {
    document.getElementById('x').innerHTML = "x = " + 
        x1/gcdmemo(x1,z);
    if(Math.abs(gcdmemo(y1,z1)) == z1) {
      document.getElementById('y').innerHTML = "y = " + 
        y1/gcdmemo(y1,z);
    }
    else {
      if(z/gcdmemo(y1,z) > 0) {
        document.getElementById('y').innerHTML = "y = " + 
        y1/gcdmemo(y1,z) + "/" + z/gcdmemo(y1,z);
      }
      else {
      document.getElementById('y').innerHTML = "y = " +
         (-1)*y1/gcdmemo(y1,z) + "/" + Math.abs(z/gcdmemo(y1,z));
      }
    }
  }
  else {
    if(z/gcdmemo(x1,z) > 0) {
      document.getElementById('x').innerHTML = "x = " + 
        x1/gcdmemo(x1,z) + "/" + z/gcdmemo(x1,z);
    }
    else {
      document.getElementById('x').innerHTML = "x = " + 
        (-1)*x1/gcdmemo(x1,z) + "/" + Math.abs(z/gcdmemo(x1,z));
    }
    if(Math.abs(gcdmemo(y1,z1)) == z1) {
      document.getElementById('y').innerHTML = "y = " + 
        y1/gcdmemo(y1,z);
    }
    else {
      if(z/gcdmemo(y1,z) > 0) {
        document.getElementById('y').innerHTML = "y = " + 
        y1/gcdmemo(y1,z) + "/" + z/gcdmemo(y1,z);
      }
      else {
        document.getElementById('y').innerHTML = "y = " + 
        (-1)*y1/gcdmemo(y1,z) + "/" + Math.abs(z/gcdmemo(y1,z));
      }
    }
  }
}


追記)分母の符号処理にバグを発見しました。謹んで訂正致します。しかしながら依然、分子か分母またそのいずれもマイナス値だった時のユークリッド互除法の符号処理に疑問があります。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です