实现以下转换字符串的函数 将浮点数表示为双精度数:
double strToDouble(char[] str)
您的实现应该能够正确处理字符串,例如:
- "123456"
- "-123.456"
- "123.456e13"
- "123.456E-13"
任何格式不正确的输入字符串都应导致值 0.0 被退回。
提示和建议:
- 使用上面的函数 strToInt 作为起点。
- 使用如果 第一个循环之后的语句,用于检查十进制等内容 点、e(用于科学记数法指数)和负号。
- 使用单独的循环来处理可能的小数点之后的内容。
- 使用另一个循环来处理可能的指数值 在 E 之后。
调用函数strToDouble后我如何回答
1)应该正确输出是这样的:
123456
-123.456000
1234560000000000.000000
0.000000
2)为什么我们需要输入 [i + 2] 和 [i+1]?我随机放置,但我对此没有解释。
-
double strToDouble(const char str[]) {
int i = 0, k = 10;
double result = 0, doubleValue, expValue = 0, resultDecimal = 0;
double exp = 1;
if (str[0] == '-')
{
i++;
}
while (str[i] >= '0' && str[i] <= '9')
{
doubleValue = str[i] - '0';
result = result * 10 + doubleValue;
i++;
}
if (str[i] == '.')
{
while (str[i + 1] >= '0' && str[i + 1] <= '9')
{
doubleValue = (str[i + 1] - '0');
resultDecimal = resultDecimal + doubleValue / k;
k *= 10;
i++;
}
}
if (str[i + 1] == 'e')
{
if (str[i + 2] == '-')
{
while (str[i + 3] >= '0' && str[i + 3] <= '9')
{
doubleValue = str[i + 3] - '0';
expValue = expValue * 10 + doubleValue;
i++;
}
for (k = 0; k < expValue; k++)
{
exp /= 10;
}
}
else
{
while (str[i + 2] >= '0' && str[i + 2] <= '9')
{
doubleValue = str[i + 2] - '0';
expValue = expValue * 10 + doubleValue;
i++;
}
for (k = 0; k < expValue; k++)
{
exp *= 10;
}
}
}
result = (result + resultDecimal) * exp;
为什么我们需要把
[i + 2]
和[i+1]
放?我随机放置,但我对此没有解释。
这些随机偏移会破坏您的代码。它适用于给定的示例,但如果您不指定周期而是指定指数,例如"1e3",它会中断,因为即使没有句点,您也会从解析句点的代码中继承偏移量:
if (str[i] == '.') {
// parse mantissa, using i + 1 as index
}
if (str[i + 1] == 'e') // i + 1 may be one beyond the character you
// should be looking at.
只有当你真的找到一个时,你才应该在句点之后前进当前字符:
if (str[i] == '.') {
i++; // step over period
// parse mantissa, using i as index
}
if (str[i] == 'e') {
i++; // step over 'e'
// parse exponent, using i as index
}
越过+
(你似乎根本不治疗)和-
(你检测到,但不考虑结果)的迹象也是如此。
换句话说:您当前正在检查的字符应始终位于索引i
。你可以向前看,但只能在上下文中。当您向前看时,您还应该确保您查看的字符不是在可能的 null 终止符之后。