3

次の方法を適用して、Double/Float形式を有理形式に変換しました。

例の場合

a=0.125
Find t=1000 
Find k=GCD(t,a*t);
Print (a*t/k) "/" t/k

0.125では正しいo/pが得られますが、0.12では得られません。問題はtを見つけることにあります。これで私を助けてください。これがコードです、

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
int gcd(int a,int b)
{
  if(b==0)
  return a;
  else
  return gcd(b,a%b);
}
void DoubleToRational(float a)
{
  int t=1;
  while((float)t*a!=(int)(t*a))
  {
   //cout<<t*a<<" "<<(float)t*a<<" "<<(int)(t*a)<<endl; // For Checking
   t=t*10;
  }
  int k=gcd(t*a,t);
  cout<<(int)t*a/k<<" / "<<t/k;
}
int main()
{
  DoubleToRational(0.125); //0.021 seconds Works Perfectly
 // DoubleToRational(0.12); //Didnt Work ????
  return 0;
}

また、精度が高い場合、この方法が効率的に機能することは期待できません。その場合の修正/その他の方法を提案してください。

4

1 に答える 1

4

数値0.125は、2進浮動小数点で正確に表すことができます。しかし、その数0.12はできません。したがって、に最も近い表現可能な数の有理数を見つけています0.12。これは間違いなくそうではありません3/25。実際、最も近い倍精度値0.12次のとおりです。

0.11999 99999 99999 99555 91079 01499 37383 83054 73327 63671 875

このタスクを適切に進めるには、値をのような2進型ではなく、10進型のデータ型で表す必要がありますdouble

上記が実際に意味をなさない場合は、次のことをよく読んでおくことをお勧めします。すべてのコンピューター科学者が浮動小数点演算について知っておくべきこと

于 2012-12-30T20:07:07.560 に答える