yukapuka
yukapuka

Reputation: 97

Strange response from program

Okay i have written up a code that converts a string to a decimal

however i am not understanding why it is core dumping on the second assert when the first one works fine

if i print out the return from the function it is actually returning what it is supposed to be returning but for some reason the assert fails

so can somebody help me understand what is going on with assert here? i dont understand why it is failing?

here is the code

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <assert.h>

double myAtoD(char *);

int main(int argc, char *argv[]){

    char *k="0.1";
    char *l="0.141";
    double m,n;

   m = myAtoD(k);
   n = myAtoD(l);

   printf("%f\n",m);
   assert(m==0.1);

   printf("%f\n",n);
   assert(n==0.141);    

    return 0;
}

double myAtoD (char *message){

   int i=0;
   int prior=0;
   double num=0;

   while(message[i]!='.'){
      prior++;
      i++;
   }

   i=0;

   prior--;

   while(message[i]!='\0'){

      if(message[i]=='.')
      i++;

      printf("num is %f\nnew number to be added is %f\n\n",num, (message[i] - '0')*pow(10,prior));  
      num += (message[i] - '0')*pow(10,prior); 
      i++;
      prior--;
   }

   return num;
}    

Upvotes: 2

Views: 101

Answers (2)

chux
chux

Reputation: 154601

A candidate improvement to myAtoD() that is more computationally stable. Although it provides a nice answer for "0.141", it may nor be the best for all input - need to do more testing. But @merlin2011 suggestion to allow a little wiggle room is good.

#include <ctype.h>
#include <math.h>

double myAtoD (const char *message){
  double num = 0.0;
  int dp = '.';
  size_t dpi;
  size_t i = 0;
  for (i=0; message[i]; i++) {
    int ch = (unsigned char) message[i];
    if (ch == dp) {
      dp = '\0';
      dpi = i;
      continue;
    }
    if (isdigit(ch)) {
      num = num*10 + (ch - '0');
    }
    else {
      break; // illegal character
    }
  }
  if (dp == '\0') {
    num /= pow10(i - dpi - 1);
  }
  return num;
}

[Edit]

A very precise and robust conversion of text to a double is non-trivial - best to do with some sort of extended precision. The above simple routine is certain to provide an answer within 2 ULP.

Upvotes: 1

merlin2011
merlin2011

Reputation: 75669

You dealing with double precision issues.

The number 0.141 cannot be represented exactly by the computer, so you will have to instead check whether it is a small epsilon away from 0.141 instead.

Here is a better assertion.

   assert(abs(n-0.141) < DBL_EPSILON);

For that constant, you will need to put #include <float.h> at the top of your source file.

Upvotes: 3

Related Questions