Thread: Help needed with strtod

  1. #1
    Registered User
    Join Date
    Apr 2008
    Posts
    87

    Help needed with strtod

    As you can see the first double value in the string i.e. 123.4444e-309 should cause underflow yet i am getting 0.000000 33.4444 -10.555 as the output. The too_small remains 0 . Have I made a mistake in my logic ?

    Code:
     #include <stdio.h>
     #include <stdlib.h>
     #include <errno.h>
     #include <math.h>
    
     int main(void)
     {
    	char s[] = "123.4444e-309 33.4444 -10.555";
    	char *endptr1, *endptr2, *endptr3;
    	double f1, f2, f3;
    	int too_big = 0;
    	int too_small = 0;
    
    	errno = 0;
    	f1 = strtod(s, &endptr1);
    	too_big |= fabs(f1) == HUGE_VAL && errno == ERANGE;
    	too_small |= f1 == 0.0 && errno == ERANGE;
    
    	errno = 0;
    	f2 = strtod(endptr1, &endptr2);
    	too_big |= fabs(f2) == HUGE_VAL && errno == ERANGE;
    	too_small |= f2 == 0.0 && errno == ERANGE;
    
    	errno = 0;
    	f3 = strtod(endptr2, &endptr3);
    	too_big |= fabs(f3) == HUGE_VAL && errno == ERANGE;
    	too_small |= f3 == 0.0 && errno == ERANGE;
    
    	if (too_big)
    	{
    		fprintf(stderr,"Overflow error\n");
    		return (1);
    	}
    	else
    	{
    		if (too_small)
    		{
    			fprintf(stderr, "Underflow error\n");
    			return (1);
    		}
    		else
    		{
    			if (s == endptr1 || endptr1 == endptr2 || endptr2 == endptr3)
    			{
    				fprintf(stderr, "Conversion failed\n");
    				return (1);
    			}
    		}
    	}
    
    	printf(" &#37;f %f %f\n", f1, f2, f3);
    	return (0);
    }
    Last edited by broli86; 07-03-2008 at 01:56 AM.

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You only need to check for ERANGE if there's underflow or overflow, nothing else.
    It's probably why you get false results.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    Registered User
    Join Date
    Apr 2008
    Posts
    87
    Quote Originally Posted by Elysia View Post
    You only need to check for ERANGE if there's underflow or overflow, nothing else.
    It's probably why you get false results.
    Ok I changed my code , please have a look :

    Code:
     int main(void)
     {
            char s[50], *ptr = NULL;
    	char *endptr1, *endptr2, *endptr3;
    	double f1, f2, f3;
    	int too_big = 0;
    
            if (fgets(s, 50, stdin) == NULL)
            {
                    fprintf(stderr, "ERROR IN INPUT STRING\n");
                    return (1);
            }
            if ((ptr = strchr(s, '\n')) != NULL)
            {
                    *ptr = '\0';
            }
    
    	errno = 0;
    	f1 = strtod(s, &endptr1);
            too_big |= errno == ERANGE;
         
    
    	errno = 0;
    	f2 = strtod(endptr1, &endptr2);
            too_big |= errno == ERANGE;
       
    
    	errno = 0;
    	f3 = strtod(endptr2, &endptr3);
            too_big |= errno = ERANGE;
    
    	if (too_big)
    	{
                    fprintf(stderr,"OUT OF RANGE OF REPRESENTABLE VALUES\n");
    		return (1);
    	}
            else
            {
                    if (s == endptr1 || endptr1 == endptr2 || endptr2 == endptr3)
                    {
                                    fprintf(stderr, "CONVERSION OF STRING FAILED\n");
    				return (1);
                    }
                    
    	}
    
    	printf(" &#37;f %f %f\n", f1, f2, f3);
    	return (0);
    }
    With this even if I type some illegible string like "24-asd;f'jf 35905ye 3ssfa" it gives me OUT OF RANGE OF REPRESENTABLE VALUES. Why not "Conversion of string failed " ? Is it still flawed ?

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    too_big |= errno == ERANGE;
    Can be just (or should be)
    too_big = (errno == ERANGE);

    Quote Originally Posted by broli86 View Post
    With this even if I type some illegible string like "24-asd;f'jf 35905ye 3ssfa" it gives me OUT OF RANGE OF REPRESENTABLE VALUES. Why not "Conversion of string failed " ? Is it still flawed ?
    Yes. Use the endptrX argument you're defined to check if the conversion is invalid.
    If the entire expression wasn't parsed, it probably means an invalid number.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Registered User
    Join Date
    Apr 2008
    Posts
    87
    Quote Originally Posted by Elysia View Post
    too_big |= errno == ERANGE;
    Can be just (or should be)
    too_big = (errno == ERANGE);


    Yes. Use the endptrX argument you're defined to check if the conversion is invalid.
    If the entire expression wasn't parsed, it probably means an invalid number.
    The endptr pointer (if not passed as NULL) will point to the start of the input string if no conversion was done. If any characters were used, it will be advanced. That's why I checked for :

    Code:
      if (s == endptr1 || endptr1 == endptr2 || endptr2 == endptr3)

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    But the string was partially parsed, so check for the end of the string.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Registered User
    Join Date
    Apr 2008
    Posts
    87
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <math.h>
    #include <string.h>
    
    int string_to_double(char *s, char **endptr, double *f)
    {
            int too_big = 0;
    
            errno = 0;
    
            *f = strtod(s, endptr);
            too_big = (errno == ERANGE);
    
            if (too_big)
            {
                    fprintf(stderr, "OUT OF RANGE OF REPRESENTABLE VALUES\n");
                    return (1);
            }
            else
            {
                    if (s == *endptr)
                    {
                            fprintf(stderr, "CONVERSION OF STRING FAILED\n");
                            return (1);
                    }
            }
    
            return (0);
    }
    
    
    int main(void)
    {
           char s[50], *ptr = NULL;
           char *endptr1, *endptr2, *endptr3;
           double f1, f2, f3;
    	 int rc;
    
           if (fgets(s, 50, stdin) == NULL)
           {
                   fprintf(stderr, "ERROR IN INPUT STRING\n");
                   return (1);
           }
           if ((ptr = strchr(s, '\n')) != NULL)
           {
                   *ptr = '\0';
           }
    
           rc = (string_to_double(s, &endptr1, &f1) == 0) &&       
                (string_to_double(endptr1, &endptr2, &f2) == 0) &&
                (string_to_double(endptr2, &endptr3, &f3) == 0);
    
    
           if (rc == 1)
           {
    	 	  printf("&#37;f %f %f\n", f1, f2, f3);
           }
                                  
           return (!rc);
    }
    This seems to work.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. free needed or not?
    By quantt in forum Linux Programming
    Replies: 3
    Last Post: 06-25-2009, 09:32 AM
  2. Problem with strtod
    By robert777 in forum C Programming
    Replies: 11
    Last Post: 11-03-2008, 12:49 PM
  3. C++ help needed
    By Enkindu in forum Projects and Job Recruitment
    Replies: 3
    Last Post: 08-31-2004, 11:24 PM
  4. More strtod troubles
    By Bajanine in forum Windows Programming
    Replies: 2
    Last Post: 03-09-2003, 01:23 PM
  5. Help with strtod and fgets..
    By Gugge in forum C Programming
    Replies: 2
    Last Post: 05-15-2002, 02:21 PM