我正在尝试将十进制数转换为其分数。十进制数字在小数位后最多有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;
}
但我得不到正确的输出,十进制数字只有双精度。请指导我应该做的事。
答案 0 :(得分:3)
如果您的浮点数为x
,那么超过10000的分数的分子将成为(x + 0.00005) * 10000
的整数部分。是否要将分数减少到最简单的项(即除以分子和分母的gcd)取决于你。
答案 1 :(得分:2)
#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;
}
问题是b
获得了3400.00但是当你(int) b
获得3399时,所以你需要添加0.5
所以这个数字可以截断为3400。
获得3400.00与3400不同,3400.00意味着该数字是圆形到3400,这就是为什么当你做(int)3400.00时它假设最接近的整数(小于你要转换的数字)是3399,但是,当你向该数字加0.5时,最后一个最接近的整数现在是3400.
如果您想更深入地了解浮点运算,请阅读What Every Computer Scientist Should Know About Floating-Point Arithmetic
答案 2 :(得分:0)
这是一个有趣的问题。 我认为你最好先阅读计算“最大公约数”的倍数方法(http://en.wikipedia.org/wiki/Greatest_common_divisor是一个很好的来源)。
实施快速和肮脏的算法,使用笔和纸进行这些计算,然后查看双精度的表示方式(符号,指数,尾数),并改进算法以利用此表示。
遗憾的是,如果不编写你的代码,我就无能为力。答案 3 :(得分:0)
使用c ++创建的算法,该算法执行十进制到小数。
#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;
}
答案 4 :(得分:0)
我的解决方案非常简单,“懒惰”,是迭代运行的,没什么花哨的。
在大多数具有不错的数学库的语言中,您只需要算法本身即可。
但是在公元前,您需要实现简单的功能,例如
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" ;
}
以标准精度(eps = .0001),您可以得到以下内容:
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
答案 5 :(得分:0)
这是我使用的算法。这是一个迭代过程,其工作方式如下:
此方法的某些功能是:
我在github上发布了该算法的代码-https://github.com/tnbezue/fraction