atof関数を自作する

K&R本 演習4-2

atofを拡張して、次のような科学記法を扱えるようにせよ。

123.45e-6

ここで、浮動小数点のうしろには、eやEと符号の付きうる指数部が続いてもよいとする。

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

double myatof(char *s) {
    double type  = 1;
    double etype = 1;
    double n = 0;
    double e = 0;
    while(*s == ' ') { s++; }
    
    if ( *s == '+' ) {
        s++;
    }
    else if ( *s == '-' ) {
        s++;
        type = -1;
    }
    
    // 整数部分の処理
    while(isdigit(*s)) {
        n = n * 10 + *s - '0';
        s++;
    }
    
    // 小数点部分の処理
    if ( *s == '.' ) {
        double i = 1;
        while(isdigit(*++s)){
            n += (*s - '0') * (i*=0.1);
        }
    }
    
    // 指数部分の処理
    if ( *s == 'e' || *s == 'E' ) {
        s++;
        if ( *s == '+' ) {
            s++;
        }
        else if ( *s == '-' ) {
            s++;
            etype = -1;
        }
        while(isdigit(*s)){
            e = e * 10 + *s - '0';
            s++;
        }
        n *= pow(10,e*etype);
    }
    
    return n * type;
}

int main (void) {
    
    printf("%f\n",123.45E6);
    printf("%f\n",myatof("123.45E6"));
    
    printf("%f\n",123.45e-6);
    printf("%f\n",myatof("123.45e-6"));
    
    return 0;
}

できました。長くなりましたが、コード自体は結構シンプルです。

今回i変数ですが、小数点の計算のときだけしか使わなかったので宣言を局所的にしてみました。

どっちが良いんでしょうね。個人的には変数はなるべく使う範囲に留めた方が良いのかなと思っています。