2

連立方程式を解くプログラムを開発しています。結果が表示されると、「x1 = 1,36842」のようになります。その「1,36842」の端数を取得したいので、このコードを書きました。

procedure TForm1.Button1Click(Sender: TObject);
var numero,s:string;
    a,intpart,fracpart,frazfatta:double;
    y,i,mcd,x,nume,denomin,R:integer;
begin
 a:=StrToFloat(Edit1.Text);  //get the value of a
 IntPart := Trunc(a);        // here I get the numerator and the denominator
 FracPart := a-Trunc(a);
 Edit2.Text:=FloatToStr(FracPart);
 numero:='1';
 for i:= 1 to (length(Edit2.Text)-2) do
 begin
  numero:=numero+'0';
 end;                       //in this loop it creates a string that has many 0 as the length of the denominator
 Edit3.text:=FloatToStr(IntPart);
 y:=StrToInt(numero);
 x:=StrToInt(Edit3.Text);
 while y <> 0 do
 begin
  R:= x mod y;
  x:=y;
  y:=R;
 end;
 mcd:=x;              //at the end of this loop I have the greatest common divisor
 nume:= StrToInt(Edit3.Text) div mcd;
 denomin:= StrToInt(numero) div mcd;
 Memo1.Lines.Add('fraction: '+IntToStr(nume)+'/'+IntToStr(denomin));
end;

それが私に与える分数が間違っているため、正しく機能しません。誰か助けてくれませんか?

4

3 に答える 3

2

連分数は、実数の適切な有理近似を見つけるために使用できます。これは JavaScript での実装です。Delphi に移植するのは簡単だと思います。

function float2rat(x) {
    var tolerance = 1.0E-6;
    var h1=1; var h2=0;
    var k1=0; var k2=1;
    var b = x;
    do {
        var a = Math.floor(b);
        var aux = h1; h1 = a*h1+h2; h2 = aux;
        aux = k1; k1 = a*k1+k2; k2 = aux;
        b = 1/(b-a);
    } while (Math.abs(x-h1/k1) > x*tolerance);

    return h1+"/"+k1;
}

たとえば、1.36842 は 26/19 に変換されます。

このアルゴリズムのライブ デモと詳細については、私のブログを参照してください。

于 2013-04-02T19:51:32.787 に答える