From 486a05ba3fc41b0c21d7b09c3cc02fc17a1a0c8a Mon Sep 17 00:00:00 2001 From: t0xa Date: Fri, 6 Feb 2026 21:55:52 +0300 Subject: [PATCH] Add 4.2 exercise --- exercices/functions/ex_4_2.c | 0 exercices/functions/ex_4_2_atof.c | 79 +++++++++++++++++++++++++++++++ exercices/functions/ex_4_2_atof.h | 1 + 3 files changed, 80 insertions(+) create mode 100644 exercices/functions/ex_4_2.c create mode 100644 exercices/functions/ex_4_2_atof.c create mode 100644 exercices/functions/ex_4_2_atof.h diff --git a/exercices/functions/ex_4_2.c b/exercices/functions/ex_4_2.c new file mode 100644 index 0000000..e69de29 diff --git a/exercices/functions/ex_4_2_atof.c b/exercices/functions/ex_4_2_atof.c new file mode 100644 index 0000000..55ae623 --- /dev/null +++ b/exercices/functions/ex_4_2_atof.c @@ -0,0 +1,79 @@ +/* +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 +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; +} diff --git a/exercices/functions/ex_4_2_atof.h b/exercices/functions/ex_4_2_atof.h new file mode 100644 index 0000000..ace3e1a --- /dev/null +++ b/exercices/functions/ex_4_2_atof.h @@ -0,0 +1 @@ +double atof(char s[]);