/* 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; }