在将字符串转换为int之前,我理解了我们在做什么,现在我们将字符串转换为double。我不明白这段代码背后的逻辑。有人可以为我澄清这一点吗?最好的问候。
#include <ctype.h>
#include <stdio.h>
//atof: convert string s to double
double atof(char s[])
{
double val, power;
int i, sign;
for (i = 0; isspace(s[i]); i++) //skip whitespace
;
sign = (s[i] == '-') ? -1 : 1;
if (s[i] == '+' || s[i] == '-')
i++;
for (val = 0.0; isdigit(s[i]); i++)
val = 10.0 * val + (s[i] - '0');
if (s[i] == '.')
i++;
for (power = 1.0; isdigit(s[i]); i++) {
val = 10.0 * val + (s[i] - '0');
power *= 10.0;
}
return sign * val / power;
}
int main()
{
char s[] = "78.93"; //output is 78.930000
printf("atof equals %f\n", atof(s));
return 0;
}
答案 0 :(得分:5)
这部分非常简单,只需跳到第一个非空白字符:
for (i = 0; isspace(s[i]); i++) //skip whitespace
;
现在我们检查第一个非空白字符是否为 - 将其设置为负数,然后跳过字符,无论是a还是+:
sign = (s[i] == '-') ? -1 : 1;
if (s[i] == '+' || s[i] == '-')
i++;
现在开始变得棘手了。让我们使用1234.5678的示例。首先,我们要处理小数点前的部分。通过查看每个数字,将其添加到val来处理,然后如果下一个数字不是小数,则将该值乘以10直到左移它并添加下一个数字。例如,对于1234.5678,我们首先看到数字1,将其添加到val以获得1的值。下一个数字是2,所以我们多个当前的val(1)乘以10得到10然后加2得到12.下一个数字是3,所以我们将当前的val(12)乘以10得到120,然后加3得到123.下一个数字是4,所以我们将当前的val(123)乘以10得到1230,然后加4到得到1234.然后&#39;。&#39;不是数字,所以我们已经完成了数字的左侧。
for (val = 0.0; isdigit(s[i]); i++)
val = 10.0 * val + (s[i] - '0');
这部分只是移过点。
if (s[i] == '.')
i++;
现在我们对左边的小数右边做同样的事情,但我们也跟踪小数点后的位数(带有幂变量)。在1234.5678的示例中,我们看到的第一个数字是5.因此,我们将当前的val(1234)乘以10,并将(12345)的5加起来。我们还将功率提高到10.0。这一直持续到我们得到123456789的val和10000.0的幂。
for (power = 1.0; isdigit(s[i]); i++) {
val = 10.0 * val + (s[i] - '0');
power *= 10.0;
}
最后,我们除以幂来得到正确位置的小数位(123456789 / 10000.0):
return sign * val / power;
答案 1 :(得分:2)
double atof(char s[])
{
double val, power;
int i, sign;
// if there is any leading 'white space', step index past it
// keep stepping index until other than white space encountered
for (i = 0; isspace(s[i]); i++)
;
// if there is a '-' char
// then indicate value is negative
// else assume value is positive
// format is: result = (condition)? true value : false value
sign = (s[i] == '-') ? -1 : 1;
// if there is a sign byte, step index past it
if (s[i] == '+' || s[i] == '-')
i++;
// initialize the result 'val'
// then loop through following characters
for (val = 0.0; isdigit(s[i]); i++)
// digits are in the range 0x30 through 0x39
// make them integers by subtracting 0x30 ('0')
// and update the result 'val'
// remembering that each successive digit pushes the current result 'val'
// to 10 times the old value then add the new 'converted' digit
val = 10.0 * val + (s[i] - '0');
// this ends the 'for' code block
// when execution gets here, encountered something other than a digit
// when a '.' encountered, step the index past it
if (s[i] == '.')
i++;
// the 'power' value is indicating how much to divide the resulting
// 'val' by to place the decimal point (if there was a decimal point)
// into the correct position
// if other than a digit encountered, exit loop
for (power = 1.0; isdigit(s[i]); i++)
{
val = 10.0 * val + (s[i] - '0'); // see above comment about a similar line of code
power *= 10.0;
} // end for
// calculate the actual value by allowing for any sign (+ or -)
// then dividing that result by 'power' to properly place the decimal point
return sign * val / power;
} // end function: atof
答案 2 :(得分:1)
略过白色空间;处理一个主要标志;计算整数部分(在Val中);跳过小数;处理小数部分(通过更新Val,好像没有小数点,但也考虑到它)。
答案 3 :(得分:0)
此代码包含3个循环
第一个循环继续阅读&#39;空格&#39;直到检测到可读的东西(标志或数字)
第二个循环计算浮点左边部分的值(xxx的值在-xxx.545中)
最后一个循环使用前一个循环的值并继续右边的&#39;点&#39; 在计算数字&#39; power&#39;这是&#39;之后元素数量的10倍。 现在我们有一个浮点数左右两部分的符号和值
现在举个简单的例子:让-12.345
sign = -1
val = 12345
power = 1000 ( 10 to the power of numbers after the '.')
result is -1 * 12345 / 1000 = -12.345