stringise DBL_DIG

M

Malcolm

/*
converts a double to decimal with no loss of accuracy.
*/
void accurate(char *out, double x)
{
char fmt[32];

sprintf(fmt, "%%.%dg", DBL_DIG);
sprintf(out, fmt, x);
}

Any way of getting rid of the first call to sprintf() ?
 
B

Ben Pfaff

Malcolm said:
sprintf(fmt, "%%.%dg", DBL_DIG);
sprintf(out, fmt, x);

Any way of getting rid of the first call to sprintf() ?

sprintf(out, "%.*g", (int) DBL_DIG, x);
 
M

Malcolm

Ben Pfaff said:
sprintf(out, "%.*g", (int) DBL_DIG, x);
Thanks. I was barking up the wrong tree with the stringise (#) operator,
which of course gives me the string "DBL_DIG".
 
M

Martin Ambuhl

Malcolm said:
/*
converts a double to decimal with no loss of accuracy.
*/
void accurate(char *out, double x)
{
char fmt[32];

sprintf(fmt, "%%.%dg", DBL_DIG);
sprintf(out, fmt, x);
}

Any way of getting rid of the first call to sprintf() ?

#define ACCURATE(s,x) sprintf((s),"%.*g",DBL_DIG,(x))
 
P

Peter Nilsson

Malcolm said:
Thanks. I was barking up the wrong tree with the stringise (#) operator,
which of course gives me the string "DBL_DIG".

That's easily fixed (See FAQ 11.17), but you're still in trouble.

AFAIK, there's nothing barring an implementation from doing any of these in
a header source...

#define DBL_DIG __DBL_DIG
#define DBL_DIG (10)
#define DBL_DIG (FLT_DIG*2)

So code like...

#define STR(x) #x
#define STRSTR(x) STR(x)

sprintf(out, "%." STRSTR(DBL_DIG) "g", x);

....is not as maximally portable as it might seem.
 
O

Old Wolf

/*
converts a double to decimal with no loss of accuracy.
*/
void accurate(char *out, double x)
{
char fmt[32];

sprintf(fmt, "%%.%dg", DBL_DIG);
sprintf(out, fmt, x);
}

#define ACCURATE(s,x) sprintf((s),"%.*g",DBL_DIG,(x))

#define ACCURATE(s,n,x) snprintf((s),(n),"%.*g",DBL_DIG,(x))

I don't mean to be a spelling nazi, but IMHO a buffer overflow
(eg. when the code is ported to a system that has a higher
value for DBL_DIG) is a more serious portability "error"
than casting malloc (which often does get pointed out on here).

Please tell me if I should refrain from future comments on this
issue :)

Also, you could go
#define ACCURATE_PF(x) "%.*g",DBL_DIG,(x)
and then
printf(ACCURATE_PF(x));
or
snprintf(s, n, ACCURATE_PF(x));
etc.
 
P

Peter Nilsson

/*
converts a double to decimal with no loss of accuracy.
*/
void accurate(char *out, double x)
{
char fmt[32];

sprintf(fmt, "%%.%dg", DBL_DIG);
sprintf(out, fmt, x);
}

#define ACCURATE(s,x) sprintf((s),"%.*g",DBL_DIG,(x))

#define ACCURATE(s,n,x) snprintf((s),(n),"%.*g",DBL_DIG,(x))

I don't mean to be a spelling nazi, but IMHO a buffer overflow
(eg. when the code is ported to a system that has a higher
value for DBL_DIG) is a more serious portability "error"
than casting malloc (which often does get pointed out on here).

Only trouble is, snprintf is only available in C99. It's a common
extension for C90 implementations, but unfortunately, it's return
value is not consistent across such implementations.
Please tell me if I should refrain from future comments on this
issue :)

Also, you could go
#define ACCURATE_PF(x) "%.*g",DBL_DIG,(x)
and then
printf(ACCURATE_PF(x));

This is generally not considered good form as it obfuscates the printf
call.
 

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

Forum statistics

Threads
474,138
Messages
2,570,804
Members
47,349
Latest member
jojonoy597

Latest Threads

Top