我正在训练我的C语言技能。我正在做一个接收浮点数的函数,应该返回一个与struct相同的分数。当我试图降低数字时,我开始看到一些奇怪的结果。我怀疑这是floor()函数的错误。
我使用Code :: Blocks,并且我已经阅读到pow()函数在使用它时会出错,所以我认为应该是这样。
我正在阅读有关floor()函数如何工作的很多知识,但是我不知道如何解决它并防止再次产生错误的数字。
我的功能是:
Fraction ftof (float f)
/* Transforms a float in a struct type fraction. */
{
Fraction frac;
int i, decimalPlaces;
float decimalPart, numerator;
decimalPlaces = 0;
printf("Number of decimal places: %d\n", decimalPlaces);
decimalPart = f - floor(f);
printf("Decimal part: %f\n\n", decimalPart);
while (decimalPart != 0)
{
decimalPlaces++;
printf("Houses number updated: %d\n", decimalPlaces);
decimalPart = decimalPart * 10;
decimalPart = decimalPart - floor(decimalPart);
printf("Decimal part updated: %f\n", decimalPart);
}
numerator = f;
frac.denominator = 1;
for (i = 0; i < decimalPlaces; i++)
{
numerator = numerator * 10;
frac.denominator = frac.denominator * 10;
}
frac.numerator = (int) floor(numerator);
writes(frac);
printf("\n");
simplification(&frac);
return frac;
}
“写”和“简化”是我写的另外两个函数,它们也写了格式化的分数和简化了的代码,但是它们经过了良好的测试,可以正常工作。
我的主要是:
int main()
{
float decimal;
while (1) {
printf("Type a decimal number: ");
scanf("%f", &decimal);
printf("Typed number: %f\n", decimal);
writes(ftof(decimal));
printf("\n\n");
}
}
使用我在函数中间放置的“ printf”,它告诉我正在计算的数字(我从来不正确地理解如何在CodeBlocks中调试),所以当我键入0.25时,它将导致1/4。但是,如果我输入一些更困难的数字(例如0.74),则会得到:
Type a decimal number: 0,74
Typed number: 0,740000
Number of decimal places: 0
Decimal part: 0,740000
Houses number updated: 1
Decimal part updated: 0,400000
Houses number updated: 2
Decimal part updated: 0,000001
Houses number updated: 3
Decimal part updated: 0,000010
Houses number updated: 4
Decimal part updated: 0,000095
Houses number updated: 5
Decimal part updated: 0,000954
Houses number updated: 6
Decimal part updated: 0,009537
Houses number updated: 7
Decimal part updated: 0,095367
Houses number updated: 8
Decimal part updated: 0,953674
Houses number updated: 9
Decimal part updated: 0,536743
Houses number updated: 10
Decimal part updated: 0,367432
Houses number updated: 11
Decimal part updated: 0,674316
Houses number updated: 12
Decimal part updated: 0,743164
Houses number updated: 13
Decimal part updated: 0,431641
Houses number updated: 14
Decimal part updated: 0,316406
Houses number updated: 15
Decimal part updated: 0,164063
Houses number updated: 16
Decimal part updated: 0,640625
Houses number updated: 17
Decimal part updated: 0,406250
Houses number updated: 18
Decimal part updated: 0,062500
Houses number updated: 19
Decimal part updated: 0,625000
Houses number updated: 20
Decimal part updated: 0,250000
Houses number updated: 21
Decimal part updated: 0,500000
Houses number updated: 22
Decimal part updated: 0,000000
0/0
512/311
我的意思是,当只有一位小数时,它的精度为0.4 * 10 = 4,但随后为4-floor(4)= 0.000001。
我该怎么办?
答案 0 :(得分:2)
浮点类型通常使用二进制尾数,这意味着可以以10为基数精确表示的数字不能以2为基数精确表示。像0.25这样的数字具有二进制的精确表示形式,但是0.4却没有。因此您无法获得确切的答案。
解决此问题的方法不是将数字读为float
,而是将其读为字符串,然后自己转换为有理数。
Fraction stof(char *s)
{
Fraction f;
long ipart, fpart;
char *p, *p2;
int i;
p = strchr(s, '.'); // look for the decimal point
ipart = strtol(s, NULL, 10); // get the integer part
if (p) {
fpart = strtol(p+1, &p2, 10); // get the fractional part, saving the end pointer
// to count digits in case of leading zeros
} else {
fpart = 0; // no . found, fractional part is 0
}
printf("ipart=%ld, fpart=%ld\n", ipart, fpart);
f.numerator = ipart; // start with just the integer part
f.denominator = 1;
for (i=0; i<(p2-p-1); i++) { // loop for each digit in the fractional part
f.numerator *= 10; // scale up the numerator and denominator
f.denominator *= 10;
}
f.numerator += fpart; // add in the fractional part
printf("fraction = %ld / %ld\n", f.numerator, f.denominator);
return f;
}