NO

Author Topic: strtod convert -i to 0, why ?  (Read 4391 times)

Alessio

  • Guest
strtod convert -i to 0, why ?
« 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.

Offline AlexN

  • Global Moderator
  • Member
  • *****
  • Posts: 391
    • Alex's Link Sammlung
Re: strtod convert -i to 0, why ?
« Reply #1 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.
best regards
 Alex ;)

Alessio

  • Guest
Re: strtod convert -i to 0, why ?
« Reply #2 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

nicolas.sitbon

  • Guest
Re: strtod convert -i to 0, why ?
« Reply #3 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...
« Last Edit: July 01, 2009, 05:33:43 pm by nicolas.sitbon »

Alessio

  • Guest
Re: strtod convert -i to 0, why ?
« Reply #4 on: July 01, 2009, 04:54:03 pm »
thank you for an alternative to strtod, should this behaviour be considered a bug ?
« Last Edit: July 01, 2009, 05:08:11 pm by Alessio »

nicolas.sitbon

  • Guest
Re: strtod convert -i to 0, why ?
« Reply #5 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;
}

nicolas.sitbon

  • Guest
Re: strtod convert -i to 0, why ?
« Reply #6 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.

Offline AlexN

  • Global Moderator
  • Member
  • *****
  • Posts: 391
    • Alex's Link Sammlung
Re: strtod convert -i to 0, why ?
« Reply #7 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.
best regards
 Alex ;)

nicolas.sitbon

  • Guest
Re: strtod convert -i to 0, why ?
« Reply #8 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.