parsing float number

D

dkk

Here is the code:
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
float f;
int part1, part4;
float part2;
char part3[6];
char s[]="1234.56abc 903";
char *p;

sscanf(s, "%2d%5e%5s%d", &part1, &part2, &part3, &part4);
printf("parse string: %s\n", s);
printf("part1=%d\n", part1);
printf("part2=%f\n", part2);
printf("part3=%s\n", part3);
printf("part4=%d\n", part4);

return 0;
}

Here is the result:
parse string: 1234.56abc 903
part1=12
part2=34.560001
part3=abc
part4=903

question is why part2 is 34.560001, I expect this number to be 34.56.
Is there a way I can get exact 34.56?
Thanks.
 
V

Vladimir S. Oka

dkk opined:
Here is the code:
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
float f;

This is not used.
int part1, part4;
float part2;

Using `double` is (almost) always better;
char part3[6];
char s[]="1234.56abc 903";
char *p;

This is not used.
sscanf(s, "%2d%5e%5s%d", &part1, &part2, &part3, &part4);

You need to pass `part3`, not `&part3` here.
printf("parse string: %s\n", s);
printf("part1=%d\n", part1);
printf("part2=%f\n", part2);
printf("part3=%s\n", part3);
printf("part4=%d\n", part4);

return 0;
}

Here is the result:
parse string: 1234.56abc 903
part1=12
part2=34.560001
part3=abc
part4=903

question is why part2 is 34.560001, I expect this number to be 34.56.
Is there a way I can get exact 34.56?

If you use `double` for `part3` (and change `sscanf()` call to use
"%5le" instead of "%5e") you will get what you're looking for -- in
this particular case. However, bear in mind that not all numbers are
exactly representable in floating point arithmetic, hence you'll
always find cases where what is stored is not what you expect.

If you really, really need exact representation, look for libraries
that support infinite precision.

--
"MSDOS didn't get as bad as it is overnight -- it took over ten years
of careful development."
(By (e-mail address removed))

<http://clc-wiki.net/wiki/Introduction_to_comp.lang.c>
 
P

pemo

dkk said:
Here is the code:
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
float f;
int part1, part4;
float part2;
char part3[6];
char s[]="1234.56abc 903";
char *p;

sscanf(s, "%2d%5e%5s%d", &part1, &part2, &part3, &part4);
printf("parse string: %s\n", s);
printf("part1=%d\n", part1);
printf("part2=%f\n", part2);
printf("part3=%s\n", part3);
printf("part4=%d\n", part4);

return 0;
}

Here is the result:
parse string: 1234.56abc 903
part1=12
part2=34.560001
part3=abc
part4=903

question is why part2 is 34.560001, I expect this number to be 34.56.
Is there a way I can get exact 34.56?
Thanks.


If this is some specific case - then...

printf("part2=%.2f\n", part2);

and see Vladimir's comments!
 
M

Martin Ambuhl

dkk said:
question is why part2 is 34.560001, I expect this number to be 34.56.
Is there a way I can get exact 34.56?

Until you can find a fraction of the form a / b = 34.56 where a and b
are integers and b is a power of the radix used in your implementation
(typically 2), not usually. This is one of the reasons that some
implementations of some languages use (or provide) BCD floating point.
 
D

David Wade

question is why part2 is 34.560001, I expect this number to be 34.56.
Is there a way I can get exact 34.56?
Thanks.

Not in standard "C". Usually "C" represents floating point as a binary
fraction. Just as you can't represent 1/3 as a decimal, you can't represent
all decimals as binary fractions. Try using a language such as REXX or COBOL
that supports decimal arithmetic.
 
J

Joe Wright

dkk said:
Here is the code:
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
float f;
int part1, part4;
float part2;
char part3[6];
char s[]="1234.56abc 903";
char *p;

sscanf(s, "%2d%5e%5s%d", &part1, &part2, &part3, &part4);
printf("parse string: %s\n", s);
printf("part1=%d\n", part1);
printf("part2=%f\n", part2);
printf("part3=%s\n", part3);
printf("part4=%d\n", part4);

return 0;
}

Here is the result:
parse string: 1234.56abc 903
part1=12
part2=34.560001
part3=abc
part4=903

question is why part2 is 34.560001, I expect this number to be 34.56.
Is there a way I can get exact 34.56?
Thanks.
The "%f" defaults to six decimals fraction part, no matter the 'truth'.
If you want only two decimals, "%.2f" does the trick.

While we're at it, note that floating point is represented in your
computer in binary, not decimal. Conversions between binary and decimal
are subject sometimes to minor error.

Integers (within range) and reals with fractional parts powers of 2 may
be evaluated the same in binary and decimal. In FP we have a binary
point (not decimal point) and .1 means one half and .01 means one
quarter, .001 is one eighth. For example all of decimal..

x.125
x.25
x.5
x.75
x.625
x.875

... can be exactly converted to binary. Decimal x.1 cannot be exactly
represented in FP binary. It gets real close.

I think I'll stop this now and write a book.
 
P

pinkfog

dkk said:
Here is the code:
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
float f;
int part1, part4;
float part2;
char part3[6];
char s[]="1234.56abc 903";
char *p;

sscanf(s, "%2d%5e%5s%d", &part1, &part2, &part3, &part4);
printf("parse string: %s\n", s);
printf("part1=%d\n", part1);
printf("part2=%f\n", part2);
printf("part3=%s\n", part3);
printf("part4=%d\n", part4);

return 0;
}

Here is the result:
parse string: 1234.56abc 903
part1=12
part2=34.560001
part3=abc
part4=903

question is why part2 is 34.560001, I expect this number to be 34.56.
Is there a way I can get exact 34.56?
Thanks.
you can try this:
sscanf("%2d%5.2lf%5s%d",&part1, &part2,part3, &part4);
then:
printf("part1:%2d\npart2:%5.2lf\npart3:%5s\npart4:%d\n",part1,
&part2,part3, &part4);
the result is what you want.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top