Exercise 4-2 (atog - String to float, scientific notation)

Chapter_4     Exercise_4-1     atof Exercise_4-3







Exercise 4-2     K&R, p. 73


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.




atog.c         download


#include <stdio.h> // for printf(), scanf()
#include <ctype.h> // for isspace(), isdigit()

#define SIZE 200 // max no of digits before and after decimal point

double atof(char []); // string to double, optional scientific notation

int main()
{
char fpn[SIZE]; // floating-point number
double d;
// valid fpn: 0, +0, -0, 0.0, -0.0, +0., 0., .0, -.0, +.0
printf("Type a floating-point decimal number (at least 1 digit), followed by \n");
printf("an optional scientific notation, [+-]?[0-9]*[.]?[0-9]*([eE][+-]?[0-9]+)?\n");
scanf("%s", fpn);

d = atof(fpn);
printf("%f\n", d);
printf("%g\n", d);

return 0;
}

double atof(char s[]) // string to double, optional scientific notation
{
double val, power;
int i, sign, exponent, expsign;

for (i = 0; isspace(s[i]); i++)
{} // skip whitespace

sign = (s[i] == '-') ? -1 : 1;
if (s[i] == '+' || s[i] == '-')
{i++;}

if ((s[i] == '\0') || (s[i] == '.' && s[i+1] == '\0'))
{
printf("\"%s\" is not a valid floating-point decimal number\n", s);
return 0.0; // should signal the error with an exception
}

for (val = 0.0; isdigit(s[i]); i++)
{ // ending '\0' of s[] is not a digit
val = 10.0 * val + (s[i] - '0');
}

if (s[i] == '.') // optional decimal point
{i++;} // skip decimal point, move to fractional part
for (power = 1.0; isdigit(s[i]); i++)
{
val = 10.0 * val + (s[i] - '0');
power *= 10.0; // power = power * 10.0;
}

if (s[i] == 'e' || s[i] == 'E') // optional exponent
{i++;} // skip 'e' or 'E', move to (signed) exponent
else {return sign * val / power;} // no exponent

// here there is an exponent
expsign = (s[i] == '-') ? -1 : 1;
if (s[i] == '+' || s[i] == '-')
{i++;} // skip sign, move to exponent

if (s[i] == '\0')
{
printf("\"%s\" is not a valid floating-point decimal number\n", s);
return 0.0; // should signal the error with an exception
}

for (exponent = 0; isdigit(s[i]); i++)
{ // ending '\0' of s[] is not a digit
exponent = 10 * exponent + (s[i] - '0');
}

while (exponent > 0) // while(exponent)
{
if (expsign < 0)
{power *= 10.0;} // we divide by power to find the return value
else {power /= 10.0;}

exponent--;
}

return sign * val / power;
}
/*
gcc atog.c -o atog
./atog
Type a floating-point decimal number (at least 1 digit), followed by
an optional scientific notation, [+-]?[0-9]*[.]?[0-9]*([eE][+-]?[0-9]+)?
.
"." is not a valid floating-point decimal number
0.000000
0

./atog
Type a floating-point decimal number (at least 1 digit), followed by
an optional scientific notation, [+-]?[0-9]*[.]?[0-9]*([eE][+-]?[0-9]+)?
+
"+" is not a valid floating-point decimal number
0.000000
0

./atog
Type a floating-point decimal number (at least 1 digit), followed by
an optional scientific notation, [+-]?[0-9]*[.]?[0-9]*([eE][+-]?[0-9]+)?
-
"-" is not a valid floating-point decimal number
0.000000
0

./atog
Type a floating-point decimal number (at least 1 digit), followed by
an optional scientific notation, [+-]?[0-9]*[.]?[0-9]*([eE][+-]?[0-9]+)?
+.
"+." is not a valid floating-point decimal number
0.000000
0

./atog
Type a floating-point decimal number (at least 1 digit), followed by
an optional scientific notation, [+-]?[0-9]*[.]?[0-9]*([eE][+-]?[0-9]+)?
-.
"-." is not a valid floating-point decimal number
0.000000
0

./atog
Type a floating-point decimal number (at least 1 digit), followed by
an optional scientific notation, [+-]?[0-9]*[.]?[0-9]*([eE][+-]?[0-9]+)?
+0.2
0.200000
0.2

./atog
Type a floating-point decimal number (at least 1 digit), followed by
an optional scientific notation, [+-]?[0-9]*[.]?[0-9]*([eE][+-]?[0-9]+)?
-.5
-0.500000
-0.5

./atog
Type a floating-point decimal number (at least 1 digit), followed by
an optional scientific notation, [+-]?[0-9]*[.]?[0-9]*([eE][+-]?[0-9]+)?
-2a1.23 // stops at non-decimal 'a'
-2.000000
-2

./atog
Type a floating-point decimal number (at least 1 digit), followed by
an optional scientific notation, [+-]?[0-9]*[.]?[0-9]*([eE][+-]?[0-9]+)?
0.2e
"0.2e" is not a valid floating-point decimal number
0.000000
0

./atog
Type a floating-point decimal number (at least 1 digit), followed by
an optional scientific notation, [+-]?[0-9]*[.]?[0-9]*([eE][+-]?[0-9]+)?
+2.3e+
"+2.3e+" is not a valid floating-point decimal number
0.000000
0

./atog
Type a floating-point decimal number (at least 1 digit), followed by
an optional scientific notation, [+-]?[0-9]*[.]?[0-9]*([eE][+-]?[0-9]+)?
123.45e-6
0.000123
0.00012345

./atog
Type a floating-point decimal number (at least 1 digit), followed by
an optional scientific notation, [+-]?[0-9]*[.]?[0-9]*([eE][+-]?[0-9]+)?
123.45E+6
123450000.000000
1.2345e+08

./atog
Type a floating-point decimal number (at least 1 digit), followed by
an optional scientific notation, [+-]?[0-9]*[.]?[0-9]*([eE][+-]?[0-9]+)?
123.45e6
123450000.000000
1.2345e+08

./atog
Type a floating-point decimal number (at least 1 digit), followed by
an optional scientific notation, [+-]?[0-9]*[.]?[0-9]*([eE][+-]?[0-9]+)?
123.45e12
123449999999999.968750
1.2345e+14

./atog
Type a floating-point decimal number (at least 1 digit), followed by
an optional scientific notation, [+-]?[0-9]*[.]?[0-9]*([eE][+-]?[0-9]+)?
123.45e-25
0.000000
1.2345e-23
*/









Chapter_4     Exercise_4-1     atof BACK_TO_TOP Exercise_4-3



Comments

Popular posts from this blog

Contents

Blogger Page Margins in Contempo