Reputation: 97
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
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
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