/* * 有理数Ratioの定義 * * 有理数は構造体Ratioで定義する. * */ struct Ratio{ int sgn; long num, den; }; /* * 重要なRatioの定義 * */ _Zero=array(Ratio); _Zero.den=1; _One=array(Ratio); _One.num=1; _One.den=1; /* * 必要なライブラリ * */ require,"FibMP.i"; func is_Ratio(a) /* DOCUMENT is_Ratio -- Ratioの真理函数 * * Ratioであれば1を返すが, それ以外は全て0を返す. * */ { if(catch(-1)) return(0); local ans,b; ans=1; if(typeof(a)=="struct_instance"){ b=a.sgn; b=a.num; b=a.den;} else ans=0; return(ans); }; func is_RI(a) /* DOCUMENT is_RI -- 有理数の真理函数 * * Yorickの整数であるか, Ratioであれば1, * それ以外は全て0を返す函数. */ { return(is_Ratio(a) || is_integer(a)); }; func I2Ratio(a) /* DOCUMENT I2Ratio -- Yorickの整数をRatioに変換. * * 引数が整数であれば有理数に変換し, * 引数が有理数の場合はそのまま返し,  * それ以外はnilを返却する. */ { local c,b; if(is_integer(a)){ c=_One; if(a<0){ c.num=-a; c.sgn=1;} else c.num=a;} else if(is_Ratio) c=a; else c=nil; return(c); }; func R2Integer(a) /* DOCUMENT R2Integer --- Ratioから整数に変換. * * 分子が0のものと約分によって分母が1になったもの * に対してのみ変換を行う. * */ { local ans; if(is_integer(a)) ans=a; else if(is_Ratio(a)){ if(a.num==0) ans=0; else if(a.den==1) ans=(1-2*a.sgn)*a.num;}; return(ans); }; func R2Double(a) /* DOCUMENT R2Double -- 浮動小数点数に変換する函数. * */ { local ans; if(is_Ratio(a)) ans=a.num*1.0/a.den; else if(is_integer(a)) ans=a*1.0; return(ans); }; func printRATIO(a) /* DOCUMENT printRATIO -- Ratioを文字を使って表示. * */ { local n,k1,k2,dv,nd,b,g; if(is_Ratio(a)){ if(a.num==0){ write,format=" %d\n",linesize=0,0;} else{ g=gcd(a.num,a.den); a.num=a.num/g; a.den=a.den/g; if(a.sgn!=0) b="- "; else b=""; n=ifloor(log10(max(a.num,a.den))+1+2*a.sgn); k2=num2str(n+1); nd=" %"+k2+"hd\n"; if(a.den==1){ write,format=nd,linesize=0,(1-2*a.sgn)*a.num;} else{ k1=num2str(n); dv=" %"+k1+"hs\n"; for(i=1;i a>b の場合 * RGr(a,b) ==0 <-> a<=bの場合 */ { local ans,a1,b1; ans=0; a1=a; b1=b; if(is_integer(a) && is_integer(b)) return(a>b); else if(is_integer(a)) a1=I2Ratio(a); else if(is_integer(b)) b1=I2Ratio(b); if(is_Ratio(a1)&& is_Ratio(b1)){ if(a1.sgn+b1.sgn==1){ if(a1.sgn==0) ans=1;} else{ ans=(1-2*a1.sgn)*a1.num*b1.den> (1-2*b1.sgn)*a1.den*b1.num;};} return(ans); }; func RLs(a,b) /* DOCUMENT RSimp -- 有理数の大小関係を判定. * * RLs(a,b) ==1 <-> a a>=bの場合 */ { local ans,a1,b1; ans=0; a1=a; b1=b; if(is_integer(a) && is_integer(b)) return(a