Pelles C forum

C language => Expert questions => Topic started by: Alessio on July 01, 2009, 12:13:00 PM

Title: strtod convert -i to 0, why ?
Post by: Alessio on July 01, 2009, 12:13:00 PM
Hi,
please look at the following code:

//
#include <stdio.h>
#include <stdlib.h>

Code: [Select]
//
#include <stdio.h>
#include <stdlib.h>

//
int main(void)
{
char *szValue = "-i";

char *p = NULL;
double a = strtod(szValue, &p);

// check for error
if ( *p && p )
{
printf("unable to convert %s\n", szValue);

return -1;
}

printf("%s converted is %g\n", szValue, a);

return 0;
}

Compiling and running with POCC.EXE: Version 5.00.13, reports that

Quote
"-i converted is 0"

Why ?
Has -i special meaning ?
Or for -i ( or -n, -I and -N ) error is not raised ?

Thank you.
Title: Re: strtod convert -i to 0, why ?
Post by: AlexN on July 01, 2009, 02:34:52 PM

Quote
"-i converted is 0"

Why ?
Has -i special meaning ?
Or for -i ( or -n, -I and -N ) error is not raised ?
"-i" is not real a number or a floating point number. When you look into the help file you can find for strtod:

Returns:
The converted value, if any. If no conversion could be performed, zero is returned.
Title: Re: strtod convert -i to 0, why ?
Post by: Alessio on July 01, 2009, 03:58:12 PM
I think this is not a correct answer.
Have you tried to use -z instead of -i ?
Why for -i or -n error is not raised ?

Try this:

Code: [Select]
//
#include <stdio.h>
#include <stdlib.h>

//
int main(void)
{
int i = 0 ;
char szValue[] = "-a";
char *p = NULL;

double a = 0.0;

for ( i = 'a'; i <= 'z'; i++ )
{
a = strtod(szValue, &p);

// check for error
if ( p && *p )
{
printf("unable to convert %s\n", szValue);
}
else
{
printf("%s converted is %g\n", szValue, a);
}

++szValue[1];
}

return 0;
}

you should get this:

Quote
unable to convert -a
unable to convert -b
unable to convert -c
unable to convert -d
unable to convert -e
unable to convert -f
unable to convert -g
unable to convert -h
-i converted is 0
unable to convert -j
unable to convert -k
unable to convert -l
unable to convert -m
-n converted is 0
unable to convert -o
unable to convert -p
unable to convert -q
unable to convert -r
unable to convert -s
unable to convert -t
unable to convert -u
unable to convert -v
unable to convert -w
unable to convert -x
unable to convert -y
unable to convert -z
Title: Re: strtod convert -i to 0, why ?
Post by: nicolas.sitbon on July 01, 2009, 04:49:57 PM
strtod sucks
Code: [Select]
#include <stdio.h>

int main(void)
{
   char str[3] = {'-'};

   for(int i = 'a'; i <= 'z'; i++)
   {
      str[1] = i;
      double a = 0.0;
      int const ret = sscanf(str, "%lg", &a);

      printf("%c :", i);

      if(ret == 1)
      {
         printf("conversion OK : a = %g\n", a);
      }
      else
      {
         puts("conversion KO");
      }
   }

   return 0;
}
Quote
a :conversion KO
b :conversion KO
c :conversion KO
d :conversion KO
e :conversion KO
f :conversion KO
g :conversion KO
h :conversion KO
i :conversion KO
j :conversion KO
k :conversion KO
l :conversion KO
m :conversion KO
n :conversion KO
o :conversion KO
p :conversion KO
q :conversion KO
r :conversion KO
s :conversion KO
t :conversion KO
u :conversion KO
v :conversion KO
w :conversion KO
x :conversion KO
y :conversion KO
z :conversion KO
Press any key to continue...
Title: Re: strtod convert -i to 0, why ?
Post by: Alessio on July 01, 2009, 04:54:03 PM
thank you for an alternative to strtod, should this behaviour be considered a bug ?
Title: Re: strtod convert -i to 0, why ?
Post by: nicolas.sitbon on July 01, 2009, 05:47:18 PM
thank you for an alternative to strtod, should this behaviour be considered a bug ?
absolutely!
Quote
3 The expected form of the subject sequence is an optional plus or minus sign, then one of
the following
:
—a nonempty sequence of decimal digits optionally containing a decimal-point
character,then an optional exponent part as defined in 6.4.4.2;
—a 0x or 0X,then a nonempty sequence of hexadecimal digits optionally containing a
decimal-point character,then an optional binary exponent part as defined in 6.4.4.2;
— INF or INFINITY,ignoring case
— NAN or NAN(n-char-sequenceopt),ignoring case in the NAN part, where:
n-char-sequence:
   digit
   nondigit
   n-char-sequence digit
   n-char-sequence nondigit

The subject sequence is defined as the longest initial subsequence of the input string,
starting with the first non-white-space character,that is of the expected form. The subject
sequence contains no characters if the input string is not of the expected form
.

Quote
7 If the subject sequence is empty or does not have the expected form, no conversion is
performed; the value of nptr is stored in the object pointed to by endptr,provided
that endptr is not a null pointer.

Quote
10 The functions return the converted value, if any. If no conversion could be performed,
zero is returned
.

test program:
Code: [Select]
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
   char str[3] = {'-'};

   for(int i = 'a'; i <= 'z'; i++)
   {
      str[1] = i;
      char * endptr = NULL;
      double a = strtod(str, &endptr);

      printf("%c : ", i);
     
      if((int)a == 0  &&  endptr == str)
      {
         puts("Good implementation");
      }
      else
      {
         puts("Bad  implementation");
      }
   }

   return 0;
}
Title: Re: strtod convert -i to 0, why ?
Post by: nicolas.sitbon on July 01, 2009, 05:51:37 PM
I guess that the incorrect behaviour for character 'i' and 'n' is a mishandling for special value like INF (or INFINITY) et NAN.
Title: Re: strtod convert -i to 0, why ?
Post by: AlexN on July 02, 2009, 08:13:21 AM
I think this is not a correct answer.
Have you tried to use -z instead of -i ?
Why for -i or -n error is not raised ?

I am not sure, if the answer is not correct. The strings like "-a" ... "-z" ,exept -"i" and "-n", are converted to -0. "-i" and "-n" are converted to 0. Why not -0, I don't know (perhaps my first answer).

Your way to check for an error is not so good. The pointer p gives you the position how far the string was read. If there a "a", "b" or something else strtod() knows that there is not a number. In the case of 'i' or 'n' there could come a string like "inf", "infinity" or "nan". Try strings like "inx", "nam" or something else and look at the pointer p. So in the case of "-i" and "-n" the hole strings is read and the string behind the pointer p is empty and you think the conversion of the string is correct.

If this behavior is correct, i don't know.
Title: Re: strtod convert -i to 0, why ?
Post by: nicolas.sitbon on July 02, 2009, 08:41:08 AM
If this behavior is correct, i don't know.
I give you above what the C99 standard says about conversion. This behaviour is not correct.