2013-team4/code/fraction
从 Trac 迁移的文章
这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。
原文章内容如下:
{{{
//java下的高精度分数模板
//和高精度分数矩阵高斯消元求逆矩阵的模板
import java.io.*;
import java.util.*;
import java.math.*;
class fraction {
public BigInteger num, den; //numerator & denominator
static public final fraction ONE=new fraction(BigInteger.ONE, BigInteger.ONE);
static public final fraction ZERO= new fraction(BigInteger.ZERO, BigInteger.ONE);
//构造而不检查
public fraction(BigInteger _num, BigInteger _den){num=_num; den=_den;}
//构造后立刻化为最简
public fraction(BigInteger _num, BigInteger _den, boolean fixit){num=_num; den=_den; fix();}
public fraction add(fraction x){
BigInteger gcd=den.gcd(x.den);
BigInteger A=x.den, B=den;
if(!gcd.equals(BigInteger.ONE)){
A=A.divide(gcd);
B=B.divide(gcd);
}
BigInteger newNum=num.multiply(A).add(x.num.multiply(B));
BigInteger newDen=den.multiply(A);
fraction t=new fraction(newNum, newDen, true);
return t;
}
public fraction negate(){return new fraction(num.negate(),den);}
public fraction subtract(fraction x){return this.add(x.negate());}
public fraction multiply(fraction x){
fraction t=new fraction(num.multiply(x.num),den.multiply(x.den),true);
return t;
}
public fraction reciprocal(){
if(num.signum()==0)return null; //divided by zero
else if(num.signum()>0)return new fraction(den, num);
else return new fraction(den.negate(), num.negate());
}
public fraction divide(fraction x){
return this.multiply(x.reciprocal());
}
public void fix(){
BigInteger gcd=num.gcd(den);
if(gcd.compareTo(BigInteger.ONE)>0){
num=num.divide(gcd);
den=den.divide(gcd);
}
if(den.signum()<0){
num=num.negate();
den=den.negate();
}
}
public int signum(){
return num.signum()*den.signum();
}
public String toString(){
fix();
String res=num.toString();
if(den.compareTo(BigInteger.ONE)!=0)res+="/"+den.toString();
return res;
}
}
class Matrix {
fraction[][] data;
Matrix(fraction[][] _data){data=_data;}
Matrix(int n, int m, int type){
data=new fraction[n][m];
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
data[i][j]=fraction.ZERO;
if(type==1){
int nn=n<m?n:m;
for(int i=0; i<nn; i++)
data[i][i]=fraction.ONE;
}
}
public void print(){
for(int i=0; i<data.length; i++){
for(int j=0; j<data[i].length; j++){
System.out.printf("%5s ",data[i][j].toString());
}
System.out.println();
}
}
boolean isSquare(){
if(data.length==0)return true;
else if(data.length==data[0].length)return true;
else return false;
}
boolean transpose(){
if(!isSquare())return false;
for(int i=0; i<data.length; i++)
for(int j=i+1; j<data[0].length; j++){
fraction tmp=data[i][j];
data[i][j]=data[j][i];
data[j][i]=tmp;
}
return true;
}
void swapRow(int i, int j){
fraction[] t=data[i];
data[i]=data[j];
data[j]=t;
}
void mulRow(int i, fraction time){
if(time.signum()==0)return;
for(int j=0; j<data[i].length; j++)
data[i][j]=data[i][j].multiply(time);
}
void addMulRow(int i, int j, fraction time){
if(time.signum()==0)return;
for(int k=0; k<data[i].length; k++)
data[j][k]=data[j][k].add(data[i][k].multiply(time));
}
Matrix invert(){
if(!isSquare())return null;
int n=data.length;
Matrix M=new Matrix(n,n,1);
for(int k=0; k<n; k++){
int row=-1;
for(int i=k; i<n; i++)
if(data[i][k].signum()!=0){
row=i;
break;
}
if(row==-1)return null;
swapRow(k, row);
M.swapRow(k, row);
fraction v=fraction.ONE.divide(data[k][k]);
for(int i=0; i<n; i++){
if(i==k)continue;
fraction t=data[i][k].negate().multiply(v);
addMulRow(k, i, t);
M.addMulRow(k, i, t);
}
mulRow(k, v);
M.mulRow(k, v);
}
return M;
}
}
}}}
//java下的高精度分数模板
//和高精度分数矩阵高斯消元求逆矩阵的模板
import java.io.*;
import java.util.*;
import java.math.*;
class fraction {
public BigInteger num, den; //numerator & denominator
static public final fraction ONE=new fraction(BigInteger.ONE, BigInteger.ONE);
static public final fraction ZERO= new fraction(BigInteger.ZERO, BigInteger.ONE);
//构造而不检查
public fraction(BigInteger _num, BigInteger _den){num=_num; den=_den;}
//构造后立刻化为最简
public fraction(BigInteger _num, BigInteger _den, boolean fixit){num=_num; den=_den; fix();}
public fraction add(fraction x){
BigInteger gcd=den.gcd(x.den);
BigInteger A=x.den, B=den;
if(!gcd.equals(BigInteger.ONE)){
A=A.divide(gcd);
B=B.divide(gcd);
}
BigInteger newNum=num.multiply(A).add(x.num.multiply(B));
BigInteger newDen=den.multiply(A);
fraction t=new fraction(newNum, newDen, true);
return t;
}
public fraction negate(){return new fraction(num.negate(),den);}
public fraction subtract(fraction x){return this.add(x.negate());}
public fraction multiply(fraction x){
fraction t=new fraction(num.multiply(x.num),den.multiply(x.den),true);
return t;
}
public fraction reciprocal(){
if(num.signum()==0)return null; //divided by zero
else if(num.signum()>0)return new fraction(den, num);
else return new fraction(den.negate(), num.negate());
}
public fraction divide(fraction x){
return this.multiply(x.reciprocal());
}
public void fix(){
BigInteger gcd=num.gcd(den);
if(gcd.compareTo(BigInteger.ONE)>0){
num=num.divide(gcd);
den=den.divide(gcd);
}
if(den.signum()<0){
num=num.negate();
den=den.negate();
}
}
public int signum(){
return num.signum()*den.signum();
}
public String toString(){
fix();
String res=num.toString();
if(den.compareTo(BigInteger.ONE)!=0)res+="/"+den.toString();
return res;
}
}
class Matrix {
fraction[][] data;
Matrix(fraction[][] _data){data=_data;}
Matrix(int n, int m, int type){
data=new fraction[n][m];
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
data[i][j]=fraction.ZERO;
if(type==1){
int nn=n<m?n:m;
for(int i=0; i<nn; i++)
data[i][i]=fraction.ONE;
}
}
public void print(){
for(int i=0; i<data.length; i++){
for(int j=0; j<data[i].length; j++){
System.out.printf("%5s ",data[i][j].toString());
}
System.out.println();
}
}
boolean isSquare(){
if(data.length==0)return true;
else if(data.length==data[0].length)return true;
else return false;
}
boolean transpose(){
if(!isSquare())return false;
for(int i=0; i<data.length; i++)
for(int j=i+1; j<data[0].length; j++){
fraction tmp=data[i][j];
data[i][j]=data[j][i];
data[j][i]=tmp;
}
return true;
}
void swapRow(int i, int j){
fraction[] t=data[i];
data[i]=data[j];
data[j]=t;
}
void mulRow(int i, fraction time){
if(time.signum()==0)return;
for(int j=0; j<data[i].length; j++)
data[i][j]=data[i][j].multiply(time);
}
void addMulRow(int i, int j, fraction time){
if(time.signum()==0)return;
for(int k=0; k<data[i].length; k++)
data[j][k]=data[j][k].add(data[i][k].multiply(time));
}
Matrix invert(){
if(!isSquare())return null;
int n=data.length;
Matrix M=new Matrix(n,n,1);
for(int k=0; k<n; k++){
int row=-1;
for(int i=k; i<n; i++)
if(data[i][k].signum()!=0){
row=i;
break;
}
if(row==-1)return null;
swapRow(k, row);
M.swapRow(k, row);
fraction v=fraction.ONE.divide(data[k][k]);
for(int i=0; i<n; i++){
if(i==k)continue;
fraction t=data[i][k].negate().multiply(v);
addMulRow(k, i, t);
M.addMulRow(k, i, t);
}
mulRow(k, v);
M.mulRow(k, v);
}
return M;
}
}