c_programming_language/exercices/functions/ex_4_2_atof.c
2026-02-06 21:55:52 +03:00

79 lines
2.4 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
Exercise 4-2. Extend atof to handle scientific notation of the form
123.45e-6, where a floating-point number may be followed by e or E and an
optionally signed exponent.
- "123.45e-6" → это означает 123.45 × 10⁻⁶ = 0.00012345
- "2.5e3" → это означает 2.5 × 10³ = 2500.0
- "1.23E+2" → это означает 1.23 × 10² = 123.0
- "5e-2" → это означает 5 × 10⁻² = 0.05
Формат научной нотации:
[число][e или E][необязательный знак +/-][показатель степени]
То есть после основного числа (которое твоя функция уже умеет парсить) может
идти:
1. Символ 'e' или 'E'
2. Необязательный знак '+' или '-'
3. Целое число (показатель степени десятки)
*/
#include <ctype.h>
double atof(char s[]) {
double val, power;
int i, sign;
// Идем до первого "не пробела"
for (i = 0; isspace(s[i]); i++)
;
// Если "-" то будем умножать на -1
sign = (s[i] == '-') ? -1 : 1;
// Если вдруг после получения знака опять идут + и - то скипаем их
if (s[i] == '+' || s[i] == '-')
i++;
/*
* Допустим у нас число 123.298
* Смотрим шаги по очереди:
* 1
* val = 10.0 * 0 + ('1' - '0') = 0 + (50 - 49) = 0 + 1 = 1
* 2
* val = 10.0 * 1 + ('2' - '0') = 1 + (51 - 49) = 10.0 + 2 = 12.0
* 3
* val = 10.0 * 12.0 + ('3' - '0') = 120.0 + (52 - 49) = 120.0 + 3 = 123.0
*/
for (val = 0.0; isdigit(s[i]); i++)
val = 10.0 * val + (s[i] - '0');
// Скипаем точку
if (s[i] == '.')
i++;
/*
* 0 49
* 1 50
* 2 51
* 3 52
* 4 53
* 5 54
* 6 55
* 7 56
* 8 57
* 9 58
* |
* Продолжаем с 123.298
* 2
* val=10.0*123.0+(s[i]-'0') = 1230.0+(51-49) = 1230.0+2 = 1232.0
* power = power * 10 = 1.0*10 = 10.0
* 9
* val=10.0*1232.0+(s[i]-'0')=12320.0+(58-49)=12329.0
* power = power * 10 = 10.0*10 = 100.0
* 8
* val=10.0*12329.0+(s[i]-'0')=123290.0+(57-49)=123298.0
* power = power * 10 = 100.0*10 = 1000.0
*/
for (power = 1.0; isdigit(s[i]); i++) {
val = 10.0 * val + (s[i] - '0');
power *= 10;
}
// 1 * (123289.0/1000) = 123.289
return sign * val / power;
}