double atof( const char *s ) s を double に変換して返す
今回は、カーニハン&リッチーの「プログラミング言語C」に示されている atof関数の処理手続きを紹介します。
以前に紹介した atoi の自前処理例 に小数部の処理を加えたものです。
#include <ctype.h> double atof( char s[] ) { double val, power; int i, sign; 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++ ) //s[i]が数字のあいだ valへ val = 10.0 * val + ( s[i] - '0' ); if( s[i] == '.' ) //ピリオドを飛ばす i++; //小数部も整数としてvalへ、後で割る値をpowerに求める for( power = 1.0; isdigit( s[i] ); i++ ) { val = 10.0 * val + ( s[i] - '0' ); power *= 10.0; } return sign * val/power; //小数に戻し符号を反映 }
【 たとえば s が "123.456" だとすると 】
まず val に 123 が入り(val は 123.0)、ピリオドを飛ばして 456 がその続きに入ります(val は 123456.0)。
power は初期値が 1.0 で、これを小数点以下のひと桁を処理するたびに 10倍しています(power は 1000.0)。
return 文の式で power で割って返すので、戻り値は 123.456 となります。
val = 10.0 * val + ( s[i] - '0' );の処理についてですが、10.0 を掛けて先ほどまでの値をひとつ上の位に押し上げ、s[i] の数字を"数値"として末の位に保存しています(atoi の自前処理例 にも説明があります)。
printf( "%f\n", atof( "0.543f" ) ); printf( "%f\n", atof( " 3." ) ); printf( "%f\n", atof( "ABC" ) ); printf( "%f\n", atof( "1e3" ) );(答えは、次回のC言語の Tips で ・・・)
int shishagonyu( double x ) { return (int)(x < 0.0 ? x-0.5 : x+0.5); }