Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 将十进制数转换成分数_C_Math - Fatal编程技术网

C 将十进制数转换成分数

C 将十进制数转换成分数,c,math,C,Math,我试图把十进制数转换成分数。小数位数在小数点后最多有4位。 示例:-12.34=1234/100 12.3456=123456/10000 我的代码:- #include <stdio.h> int main(void) { double a=12.34; int c=10000; double b=(a-floor(a))*c; int d=(int)floor(a)*c+(int)b; while(1) { if(d%10==0) { d=

我试图把十进制数转换成分数。小数位数在小数点后最多有4位。 示例:-12.34=1234/100 12.3456=123456/10000

我的代码:-

#include <stdio.h>
int main(void) {
  double a=12.34;
  int c=10000;
  double b=(a-floor(a))*c;
  int d=(int)floor(a)*c+(int)b; 
  while(1) {
     if(d%10==0) {
    d=d/10;
    c=c/10;
 }
 else break;
  }
  printf("%d/%d",d,c);
 return 0;
}
#包括
内部主(空){
双a=12.34;
int c=10000;
双b=(a层(a))*c;
内部d=(内部)楼层(a)*c+(内部)b;
而(1){
如果(d%10==0){
d=d/10;
c=c/10;
}
否则就断了;
}
printf(“%d/%d”,d,c);
返回0;
}

但是我没有得到正确的输出,十进制数只能是双精度的。请指导我该怎么做。

如果你的浮点数是
x
,那么分数超过10000的分子将是
(x+0.00005)*10000的整数部分。这取决于你是否想将分数简化为最简单的项(即除以分子和分母的gcd)。

这是一个有趣的问题。 我认为你最好从阅读计算“最大公约数”的倍数方法开始(这是一个很好的来源)

实现一个快速脏算法,像用笔和纸一样进行这些计算,然后研究如何表示双精度(符号、指数、尾数),并改进算法以利用这种表示

遗憾的是,如果不编写您的代码,我就无能为力了。

\include
#include <stdio.h>

int main(void) {
    double a = 12.34;
    int c = 10000;
    double b = (a - floor(a)) * c;
    int d = (int)floor(a) * c + (int)(b + .5f); 
    printf("%f %d\n", b, d);

    while(1) {
       if(d % 10 == 0) {
           d = d / 10;
           c = c / 10;
       }
       else break;
    }
    printf("%d/%d\n", d, c);
    return 0;
}
内部主(空){ 双a=12.34; int c=10000; 双b=(a-楼层(a))*c; 内部d=(内部)楼层(a)*c+(内部)(b+.5f); printf(“%f%d\n”,b,d); 而(1){ 如果(d%10==0){ d=d/10; c=c/10; } 否则就断了; } printf(“%d/%d\n”,d,c); 返回0; }
问题是
b
得到的是3400.00,但当你这样做
(int)b
时,你得到的是3399,因此你需要添加
0.5
,这样数字就可以截断为3400

得到3400.00与得到3400不同,3400.00意味着数字被四舍五入到3400,这就是为什么当你做(int)3400.00时,它假设最接近的整数(小于你正在转换的数字)是3399,然而,当你把0.5加到这个数时,最后一个最接近的整数现在是3400


如果你想深入了解浮点运算,阅读< /P> < P>一个用C++生成的算法,它可以做小数到小数。p>

#include <iostream>
using namespace std;


// converts the string half of the inputed decimal number into numerical values
void converting (string decimalNumber, float& numerator, float& denominator )

{
float number;
string valueAfterPoint = decimalNumber.substr(decimalNumber.find(".") + 1,((decimalNumber.length() -1) )); // store the value after the decimal into a valueAfterPoint
cout << valueAfterPoint<< " "<< endl;
int length = valueAfterPoint.length(); //stores the length of the value after the decimal point into length

 numerator = atof(valueAfterPoint.c_str()); // converts the string type decimal number into a float value and stores it into the numerator

// loop increases the decimal value of the numerator and the value of denominator by multiples of ten as long as the length is above zero of the decimal

cout << length<< endl;
for (; length > 0; length--)
{
    numerator *= 10;

}
do
    denominator *=10;
    while  (denominator < numerator);

}

// simplifies the the converted values of the numerator and denominator into simpler values for          an easier to read output
  void simplifying (float& numerator, float& denominator)
{
int maximumNumber = 9; //Numbers in the tenths place can only range from zero to nine so the maximum number for a position in a poisitino for the decimal number will be nine

bool isDivisble; // is used as a checker to verify whether the value of the numerator has the       found the dividing number that will a value of zero

// Will check to see if the numerator divided denominator is will equal to zero



if(int(numerator) % int(denominator) == 0)
{
    numerator /= denominator;
    denominator = 1;
    return;
}


//check to see if the maximum number is greater than the denominator to simplify to lowest form
while (maximumNumber < denominator)
{
    maximumNumber *=10;
 }


// the maximum number loops from nine to zero. This conditions stops if the function isDivisible is true
for(; maximumNumber > 0; maximumNumber --)
{

    isDivisble = ((int(numerator) % maximumNumber == 0) && int(denominator)% maximumNumber == 0);
    cout << numerator << denominator <<" " <<endl;
    if(isDivisble)
    {
        numerator /= maximumNumber;  // when is divisible true numerator be devided by the max    number value for example 25/5 = numerator = 5

        denominator /= maximumNumber; //// when is divisible true denominator be devided by the max number value for example 100/5 = denominator = 20

    }
    // stop value if numerator and denominator is lower than 17 than it is at the lowest value
    int stop = numerator + denominator;

    if (stop < 17)
    {
        return;
    }
}
}
  int main()
{
string decimalNumber;
float numerator = 0;
float denominator = 1;

cout << "Enter the decimal number";
cin >> decimalNumber;

//convert function
converting(decimalNumber, numerator, denominator);


//call simplyfication funcition
simplifying(numerator, denominator);


cout<< "Fraction: "<< numerator << "/" << denominator<< endl;
 return 0; 

}
#包括
使用名称空间std;
//将输入的十进制数的字符串一半转换为数值
无效转换(字符串小数、浮点和分子、浮点和分母)
{
浮点数;
字符串valueAfterPoint=decimalNumber.substr(decimalNumber.find(“.”+1,((decimalNumber.length()-1));//将小数点后的值存储到valueAfterPoint中

cout我的解决方案非常简单,“懒惰”,通过迭代运行,没有什么特别之处

在大多数有像样的数学库的语言中,您只需要algo本身

但是在bc中,您需要实现简单的函数,例如

int() to return integer part of a number ,
abs() to return absolute value ,
float() to return floating part of a number ,
round() to round to nearest integer.
如果在(1/eps)迭代后未找到任何内容,则循环将以最后一个结果中断

eps=10^-4 /*Tweak for more or less accuracy */

define int(x) {
  auto s ;
  s = scale ;
  scale = 0 ;
  x /= 1 ;
  scale = s ;
  return x ;
}
define round(x) { return int(x+.5-(x<0)) ; }
define abs(x) { if ( x < 0 ) x=-x ; return x ; }
define float(x) { return abs(x-int(x)) ; }

define void frac(x) {
    auto f, j, n, z ;
    f = float(x) ;    
    j = 1 / eps ;
    z = .5 ;
    if ( f != 0 ) {
        while ( ( n++ < j ) && ( abs( z - round(z) ) > eps ) ) z = n / f ;
        n -= 1 ;
        if ( x < 0 ) n = -n ;
        x = int(x)
        z = round(z) ;
        print n + x*z , "/" , z , " = "
        if ( x != 0 )  print x , " + " , n , "/" , z , " = "
    }
    print x+n/z , "\n" ;
}

这是我使用的算法。它是一个迭代过程,工作如下:

  • 分子的初始近似值为1,分母为1除以浮点值的分数部分。例如,将0.06转换为分数时,分母=1/0.06=16.666667(四舍五入为17),因此初始近似值为1/17
  • 计算浮点值与当前近似值之间的差值。例如,差值为1/17-0.06=0.058824-0.06=-0.001176
  • 如果差值的绝对值小于定义的公差(即0.000005),则迭代终止
  • 使用第2步中计算的差值改进分数的近似值。这是通过将差值转换为分数并加(或减)来实现的到当前近似值。在本例中,负差值表示低近似值——因此需要将差值添加到当前近似值中。差值分数为分子=1,分母=1/0.001176=850——与的分数差为1/850。新的近似值为(1/17)+(1/850)=(850*1+17*1)/(850*17)=867/14450
  • 重复步骤2至4,直到找到解决方案
  • 找到解后,分数可以减少。例如,867/14450正好是0.06,迭代过程终止。867/14450可以减少到3/50
  • 这种方法的一些特点是:

    • 如果结果分数为1/4,则第一近似值将是精确的。例如,将0.25转换为分数,第一近似值将是1/4。因此不需要进一步迭代
    • 在1000000个测试用例中的大多数(>80%)中,收敛发生在2次或更少的迭代中
    • 对于所有测试用例,最大迭代次数为3次

    我在github上发布了这个算法的代码--

    根本不使用浮点,而是使用定点整数,即使您的单位为1/10000。
    int d=(int)round(a*c)
    将是一个很好的起点。如果你只使用
    floor
    和截断,像
    12.34=12.33999999999857891452847979962825775146484375
    这样的东西会让你很难接受。但是我同意Kerrek的观点,你应该从一开始就使用整数。被标记为这个的副本,即使它是关于JavaScript的,而不是C.:/这并不能真正回答问题-它只会提示提问者搜索他们自己问题的答案/
    frac(-.714285)
    -5/7 = -.71428571428571428571
    
    sqrt(2)
    1.414213562373
    frac(sqrt(2))
    19601/13860 = 1 + 5741/13860 = 1.414213564213
    
    6-7/pi
    3.77183080
    eps=.000001 ; frac(6-7/pi)
    1314434/348487 = 3 + 268973/348487 = 3.77183080