patterncMinor
getfloat, the floating point analog of getint
Viewed 0 times
thepointfloatinggetfloatgetintanalog
Problem
Write getfloat, the floating-point analog of getint. What types does getfloat return as its function value?
Here is my solution:
I have changed the type of the parameter
The second
gefloat would also return an integer value.Here is my solution:
int getfloat(double *pf) {
int c, sign;
double power;
while(isspace(c = getch()))
;
if(!isdigit(c) && c != EOF && c != '-' && c != '+' && c != '.') {
ungetch(c); /* push the number back in buffer */
return 0; /* not a valid number */
}
sign = (c == '-') ? -1 : 1;
if(c == '-' || c == '+')
c = getch();
if(!isdigit(c) && c != '.') {
ungetch(c);
return 0; /* not a number */
}
for(*pf = 0.0; isdigit(c); c = getch())
*pf = *pf * 10 + (c - '0');
if(c == '.')
c = getch();
for(power = 1.0; isdigit(c); c = getch()) {
*pf = *pf * 10 + (c - '0');
power *= 10;
}
*pf *= sign;
*pf /= power; /* moving the decimal point */
if(c != EOF)
ungetch(c);
return c; /* it actually returns the value of the charachter that caused the break of the second for */
}I have changed the type of the parameter
*pf to double, thus it will handle the floating point represenation of a number. The condition of the first if-statement was extended, such that it will not push back in to the buffer a decimal point.The second
for computes the decimal part of the number, storing the number of places that the decimal point should pe moved in the variable power. If there is no decimal part, power will have the value 1 - thus, nothing will change if I devide *pf by power when power is 1.Solution
-
It obviously does not handle
-
Surprisingly does not handle exponential notation such as 1.23e+56.
-
-
Minor: The
-
This is a pedantic point: Once you get about 17 (depends on
-
The
-
-
With
-
The decimal point
-
You are commended for for taking in
-
[Edit] IEEE_754-2008 Character_representation discusses the maximum number of non-zero leading digits to use when converting from text to a number.
It obviously does not handle
NAN and INF. Maybe outside code's goals.-
Surprisingly does not handle exponential notation such as 1.23e+56.
-
if(!isdigit(c) && c != '.') { returns a 0 implying "not a number" and ungets the offending c. But a potential + or - was all ready consumed and not available for alternative parsings. Not sure best way to handle, but maybe consider that once a non-white-space char is irrevocable consumed, this function should not return a error signal and should set *pf to _something_like 0 or NAN.-
Minor: The
pf /= power; approach fails with input such as 123.00000...(300+ zeros) as power or pf already became INF.-
This is a pedantic point: Once you get about 17 (depends on
double) decimal digits, the addition of (c - '0') to pf 10 becomes moot. To get a more accurate significand, forming the number right-to-left has precision advantages.-
The
return c; could return 0 indicating "not a number" . Recommend an alternative return value scheme.-
ungetch is not in the C spec. Consider ungetc().-
With
ungetc() "If the value of c equals that of the macro EOF, the operation fails and the input stream is unchanged." thus negating the need for the if(c != EOF). Still not bad to have there.-
The decimal point
. is locale sensitive and could be , or something else. Use locale sensitive routines to determine the current decimal point.-
You are commended for for taking in
"-0" and rendering -0.0 rather than 0.0.-
[Edit] IEEE_754-2008 Character_representation discusses the maximum number of non-zero leading digits to use when converting from text to a number.
double is often a IEEE_754 binary64, so a maximum number to use is 17+3. This goes into point #3 above. Its a bit deep on how this affects things, but I'll just note it for those who want to delve into a portable robust solution.Context
StackExchange Code Review Q#40379, answer score: 7
Revisions (0)
No revisions yet.