- コンパイラ: GCC 4.7.2 (Debian 4.7.2-5)
- プラットフォーム: Linux 3.2.0 x86 (Debian 7.1)
独自の文字列を float 変換関数に記述しようとしています。これは基本的に の安価なぼったくりですがstrtof()
、正確に模倣することはできませんstrtof()
。私の機能がstrtof()
正確に模倣されるとは思っていませんが、なぜどこで違うのか知りたいです。いくつかの異なる文字列をテストしましたが、次の文字列は、 が関数に与えられたときと、 に与えられたとき、strtof()
および を使用して出力されたときに、異なる値を持つことがわかりましたprintf("%.38f"))
。
- 1234.5678
- 44444.44444
- 333.333
- 777.777
なぜこれが起こるのですか?(また、他の間違いを指摘したり、異なる値を持つ他の文字列を教えてください (すべてを見つける方法はありません)。)
#include <stdlib.h>
#include <stdio.h>
#include <float.h>
#include <math.h>
int dec_to_f(char *dec, float *f)
{
int i = 0;
float tmp_f = 0;
if(dec == NULL) return 1;
if(f == NULL) return 2;
if(dec[i] == '\000') return 3;
if(dec[i] == '-')
{
i++;
if(dec[i] == '\000') return 3;
for(; dec[i] != '\000'; i++)
{
if(dec[i] == '.')
{
float dec_place = 10;
int power_of_ten = 1;
for(i++; dec[i] != '\000'; i++, power_of_ten++, dec_place *= 10)
{
if(dec[i] >= '0' && dec[i] <= '9')
{
if(power_of_ten > FLT_MAX_10_EXP) return 4;
else tmp_f -= (dec[i] - '0') / dec_place;
}
else return 5;
}
break;
}
if(dec[i] >= '0' && dec[i] <= '9')
{
tmp_f = tmp_f * 10 - (dec[i] - '0');
if(!isfinite(tmp_f)) return 6;
}
else return 5;
}
}
else
{
if(dec[i] == '+')
{
if(dec[i+1] == '\000') return 3;
else i++;
}
for(; dec[i] != '\000'; i++)
{
if(dec[i] == '.')
{
float dec_place = 10;
int power_of_ten = 1;
for(i++; dec[i] != '\000'; i++, power_of_ten++, dec_place *= 10)
{
if(dec[i] >= '0' && dec[i] <= '9')
{
if(power_of_ten > FLT_MAX_10_EXP) return 7;
else tmp_f += (dec[i] - '0') / dec_place;
}
else return 5;
}
break;
}
if(dec[i] >= '0' && dec[i] <= '9')
{
tmp_f = tmp_f * 10 + (dec[i] - '0');
if(!isfinite(tmp_f)) return 8;
}
else return 5;
}
}
*f = tmp_f;
return 0;
}
int main()
{
printf("FLT_MIN = %.38f\n", FLT_MIN);
printf("FLT_MAX = %f\n", FLT_MAX);
float f = 0;
int return_value = 0;
char str[256];
printf("INPUT = ");
scanf("%s", str);
return_value = dec_to_f(str, &f);
printf("return_value = %i\nstr = \"%s\"\nf = %.38f\nstrtof = %.38f\n", return_value, str, f, strtof(str, NULL));
}