Velocity Reviews > Convert float to string without trailing 0s

# Convert float to string without trailing 0s

Mike
Guest
Posts: n/a

 04-15-2005
Hi there,

I am trying to convert a float/double number to a string using the
sprintf().
For example, if I have a float number 123.456, and I want to convert
it to "123.456". But with the sprintf() function, I always get
"123.456001". My question is how can I get the expected string without
those trailing 0s?

Mike

Martin Ambuhl
Guest
Posts: n/a

 04-15-2005
Mike wrote:
> Hi there,
>
> I am trying to convert a float/double number to a string using the
> sprintf().
> For example, if I have a float number 123.456, and I want to convert
> it to "123.456". But with the sprintf() function, I always get
> "123.456001". My question is how can I get the expected string without
> those trailing 0s?

#include <stdio.h>

int main(void)
{
double dx = 123.456;
float fx = 123.456f;
long double ldx = 123.456L;

printf("This example uses 'printf'.\n"
"It is obviously trivial to change it to use sprintf.\n\n");
printf("Printing 123.456\n"
" using %%f %f, %%g %g, %%.6g %.6g, %%.3f %.3f\n\n",
dx, dx, dx, dx);
printf("Printing 123.456f\n"
" using %%f %f, %%g %g, %%.6g %.6g, %%.3f %.3f\n\n",
fx, fx, fx, fx);
printf("Printing 123.456L\n"
" using %%Lf %Lf, %%Lg %Lg, %%.6Lg %.6Lg, %%.3Lf %.3Lf\n\n",
ldx, ldx, ldx, ldx);
return 0;
}

This example uses 'printf'.
It is obviously trivial to change it to use sprintf.

Printing 123.456
using %f 123.456000, %g 123.456, %.6g 123.456, %.3f 123.456

Printing 123.456f
using %f 123.456001, %g 123.456, %.6g 123.456, %.3f 123.456

Printing 123.456L
using %Lf 123.456000, %Lg 123.456, %.6Lg 123.456, %.3Lf 123.456

Mike.Hao@gmail.com
Guest
Posts: n/a

 04-15-2005
That's what I want. Thank you so much, Martin.

Mike

Martin Ambuhl wrote:
> Mike wrote:
> > Hi there,
> >
> > I am trying to convert a float/double number to a string using the
> > sprintf().
> > For example, if I have a float number 123.456, and I want to

convert
> > it to "123.456". But with the sprintf() function, I always get
> > "123.456001". My question is how can I get the expected string

without
> > those trailing 0s?

>
> #include <stdio.h>
>
> int main(void)
> {
> double dx = 123.456;
> float fx = 123.456f;
> long double ldx = 123.456L;
>
> printf("This example uses 'printf'.\n"
> "It is obviously trivial to change it to use

sprintf.\n\n");
> printf("Printing 123.456\n"
> " using %%f %f, %%g %g, %%.6g %.6g, %%.3f %.3f\n\n",
> dx, dx, dx, dx);
> printf("Printing 123.456f\n"
> " using %%f %f, %%g %g, %%.6g %.6g, %%.3f %.3f\n\n",
> fx, fx, fx, fx);
> printf("Printing 123.456L\n"
> " using %%Lf %Lf, %%Lg %Lg, %%.6Lg %.6Lg, %%.3Lf

%.3Lf\n\n",
> ldx, ldx, ldx, ldx);
> return 0;
> }
>
>
> This example uses 'printf'.
> It is obviously trivial to change it to use sprintf.
>
> Printing 123.456
> using %f 123.456000, %g 123.456, %.6g 123.456, %.3f 123.456
>
> Printing 123.456f
> using %f 123.456001, %g 123.456, %.6g 123.456, %.3f 123.456
>
> Printing 123.456L
> using %Lf 123.456000, %Lg 123.456, %.6Lg 123.456, %.3Lf 123.456

Chris Croughton
Guest
Posts: n/a

 04-15-2005
On 15 Apr 2005 11:49:33 -0700, Mike
<(E-Mail Removed)> wrote:

> I am trying to convert a float/double number to a string using the
> sprintf().
> For example, if I have a float number 123.456, and I want to convert
> it to "123.456". But with the sprintf() function, I always get
> "123.456001". My question is how can I get the expected string without
> those trailing 0s?

Use %g, not %f (%g will automatically go to 'scientific' format when the
number is too big or too small, though). If you know that you only want
a certain number of decomal places, you can use %.3f (for example).

Chris C

Keith Thompson
Guest
Posts: n/a

 04-15-2005
http://www.velocityreviews.com/forums/(E-Mail Removed) (Mike) writes:
> I am trying to convert a float/double number to a string using the
> sprintf().
> For example, if I have a float number 123.456, and I want to convert
> it to "123.456". But with the sprintf() function, I always get
> "123.456001". My question is how can I get the expected string without
> those trailing 0s?

No you don't have 123.456; that value isn't exactly representable in
binary floating-point. You probably have something like
123.45600128173828125, and sprintf() is doing exactly what you asked
it to.

You can limit the precision with a format specifier:

#include <stdio.h>
int main(void)
{
float f = 123.456;
char s[80];
sprintf(s, "%.20f", f);
printf("s = \"%s\"\n", s);
sprintf(s, "%.3f", f);
printf("s = \"%s\"\n", s);
return 0;
}

produces:

s = "123.45600128173828125000"
s = "123.456"

Determining how many digits to use is left as an excercise (it's not
necessarily obvious).

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.

Keith Thompson
Guest
Posts: n/a

 04-15-2005
Keith Thompson <(E-Mail Removed)> writes:
> (E-Mail Removed) (Mike) writes:
>> I am trying to convert a float/double number to a string using the
>> sprintf().
>> For example, if I have a float number 123.456, and I want to convert
>> it to "123.456". But with the sprintf() function, I always get
>> "123.456001". My question is how can I get the expected string without
>> those trailing 0s?

>
> No you don't have 123.456; that value isn't exactly representable in
> binary floating-point. You probably have something like
> 123.45600128173828125, and sprintf() is doing exactly what you asked
> it to.

And I forgot to mention: Read section 14 of the C FAQ
<http://www.eskimo.com/~scs/C-faq/top.html>.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.

Mike
Guest
Posts: n/a

 04-18-2005
Hi All,

Thank you all for your replies. Now I got a new problem when I tried
to use the sprintf() with double arrays. I have two double arrays,
e.g.:

double values[] = {1234, 23456.89};
double values2[] = {34709.22, 3746.55, 23456};

After applied to sprinf(), I got:

{"1234", "23456.9"}
{"34709.2", "3746.55", "23456"}

Since what I want to do is a "pure" conversion from floating point to
string, and I don't know what the precision is in advance, so how
should I do it?

Thanks again.

Mike

Keith Thompson <(E-Mail Removed)> wrote in message news:<(E-Mail Removed)>...
> Keith Thompson <(E-Mail Removed)> writes:
> > (E-Mail Removed) (Mike) writes:
> >> I am trying to convert a float/double number to a string using the
> >> sprintf().
> >> For example, if I have a float number 123.456, and I want to convert
> >> it to "123.456". But with the sprintf() function, I always get
> >> "123.456001". My question is how can I get the expected string without
> >> those trailing 0s?

> >
> > No you don't have 123.456; that value isn't exactly representable in
> > binary floating-point. You probably have something like
> > 123.45600128173828125, and sprintf() is doing exactly what you asked
> > it to.

>
> And I forgot to mention: Read section 14 of the C FAQ
> <http://www.eskimo.com/~scs/C-faq/top.html>.

Walter Roberson
Guest
Posts: n/a

 04-18-2005
In article <(E-Mail Removed) >,
Mike <(E-Mail Removed)> wrote:
>Since what I want to do is a "pure" conversion from floating point to
>string, and I don't know what the precision is in advance, so how
>should I do it?

You cannot. Most numbers have no exact representation as floating
point / double . For example, no matter what the precision you use,
there is no exact representation for 1/3 or even 0.3 . When
your code has double values[] = {1234, 23456.89};
then the knowledge that the second number had exactly two decimal
places is gone and what gets stored internally is a number which
is -close to- 23456.89, but not exactly the same.
--
"No one has the right to destroy another person's belief by
demanding empirical evidence." -- Ann Landers

Al Bowers
Guest
Posts: n/a

 04-18-2005

Mike wrote:
> Hi All,
>
> Thank you all for your replies. Now I got a new problem when I tried
> to use the sprintf() with double arrays. I have two double arrays,
> e.g.:
>
> double values[] = {1234, 23456.89};
> double values2[] = {34709.22, 3746.55, 23456};
>
> After applied to sprinf(), I got:
>
> {"1234", "23456.9"}
> {"34709.2", "3746.55", "23456"}
>
> Since what I want to do is a "pure" conversion from floating point to
> string, and I don't know what the precision is in advance, so how
> should I do it?
>

It seems that this question has been answered.
I might add that you can write code to remove trailing '0'
as function DoubletoStr does below, but you will still
have problems addressed in the faq question 14.1 at
http://www.eskimo.com/~scs/C-faq/q14.1.html

#include <stdio.h>
#include <string.h>

char *DoubletoStr(char *s, double dd);

int main(void)
{
double values[] = {1234, 23456.89};
double values2[] = {34709.22, 3746.55, 23456};
char value[32];
int i;

for(i = 0; i < 2;i++)
printf("values[%d] = \"%s\"\n",i,
DoubletoStr(value,values[i]));
putchar('\n');
for(i = 0; i < 3;i++)
printf("values2[%d] = \"%s\"\n",i,
DoubletoStr(value,values2[i]));
return 0;
}

char *DoubletoStr(char *s, double dd)
{
char *endp;

sprintf(s,"%f",dd);
for(endp = s+strlen(s); endp!=s;endp--)
{
if(*(endp-1) != '0'&& *(endp-1) != '.')
{
*endp = '\0';
break;
}
}
return s;
}

--
Al Bowers
Tampa, Fl USA
mailto: (E-Mail Removed) (remove the x to send email)
http://www.geocities.com/abowers822/

Martin Ambuhl
Guest
Posts: n/a

 04-18-2005
Mike wrote:
> Hi All,
>
> Thank you all for your replies. Now I got a new problem when I tried
> to use the sprintf() with double arrays. I have two double arrays,
> e.g.:
>
> double values[] = {1234, 23456.89};
> double values2[] = {34709.22, 3746.55, 23456};
>
> After applied to sprinf(), I got:
>
> {"1234", "23456.9"}
> {"34709.2", "3746.55", "23456"}
>
> Since what I want to do is a "pure" conversion from floating point to
> string, and I don't know what the precision is in advance, so how
> should I do it?

#include <stdio.h>
#include <float.h>

int main(void)
{
double values[] = { 1234, 23456.89 };
double values2[] = { 34709.22, 3746.55, 23456 };
size_t i;

printf("double values[] -> \"");
for (i = 0; i < 2; i++)
printf("%.*g\"%s", DBL_DIG, values[i], (i) ? "\n" : ", ");

printf("double values2[] -> \"");
for (i = 0; i < 3; i++)
printf("%.*g\"%s", DBL_DIG, values2[i], (i == 2) ? "\n" : ", ");

return 0;
}

[output]
double values[] -> "1234", 23456.89"
double values2[] -> "34709.22", 3746.55", 23456"