演習 4-2

無職の間にK&Rを再読。演習問題の解答をさらす。解く順番は適当。

演習 4-2
atof を拡張して、次のような科学記法を扱えるようにせよ。
  123.45e-6
ここで、浮動小数点数のうしろには、eE と符号の付きうる指数部が続いてもよいとする。


Exercise 4-2
Extend atof to handle scientific notation of the form
  123.45e-6
where a floating-point number may be followed bu e or E and an optionally signed exponent.


元になっている atof が、無駄なく美しすぎる。

#include <stdio.h>
#include <ctype.h>

double atof(char s[])
{
  double val, power, epower;
  int i, sign, e;
  
  for (i = 0; isspace(s[i]); i++)
    ;
  
  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 *= 0.1;
  }
  
  if (s[i] == 'e' || s[i] == 'E')
    i++;

  epower = (s[i] == '-') ? 0.1 : 10.0;
  if (s[i] == '+' || s[i] == '-')
    i++;
  
  for (e = 0; isdigit(s[i]); i++)
    e = 10 * e + s[i] - '0';
  
  while (e--)
    power *= epower;
  
  return sign * val * power;
}


int main(void)
{
  printf("%f\n", atof("123.45"));
  printf("%f\n", atof("123.45e2"));
  printf("%f\n", atof("123.45e-6"));
  printf("%f\n", atof(".45e-2"));
  printf("%f\n", atof("123e3"));

  return 0;
}