C 将十进制数转换成分数
我试图把十进制数转换成分数。小数位数在小数点后最多有4位。 示例:-12.34=1234/100 12.3456=123456/10000 我的代码:-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=
#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