Discussion:
sprintf a float and getting at least a single decimal - How ?
(too old to reply)
R.Wieser
2018-05-10 13:17:32 UTC
Permalink
Hello All,

Upto now I've, using wsprintf of user32.dll, simply printed a float using
"%g" as the format. The drawback of that is that, when the float has no
fractional part, it doesn't print a decimal dot and as such it gets
indistinguishable from an int.

So I went looking for a way to print something which would always print a
decimal point and at least a single decimal right of it. But alas.
Either all I get is a decimal dot with no decimals ("%#.g") or a fixed
number of decimals ("%#.3g" or "%#g") . None of which are what I'm looking
for.

And although I entertained the thought of using the last format ("%#g") and
than nibbeling off zeroes from the right, that would cause problems when the
result isn't a simple float (but one with an exponent). In other words,
mucking about the resulting string doesn't look like a good idea ...

Does anyone have an idea how to go about this ?

Regards,
Rudy Wieser
Les Cargill
2018-05-12 02:15:36 UTC
Permalink
Post by R.Wieser
Hello All,
Upto now I've, using wsprintf of user32.dll, simply printed a float using
"%g" as the format. The drawback of that is that, when the float has no
fractional part, it doesn't print a decimal dot and as such it gets
indistinguishable from an int.
So I went looking for a way to print something which would always print a
decimal point and at least a single decimal right of it. But alas.
Either all I get is a decimal dot with no decimals ("%#.g") or a fixed
number of decimals ("%#.3g" or "%#g") . None of which are what I'm looking
for.
And although I entertained the thought of using the last format ("%#g") and
than nibbeling off zeroes from the right, that would cause problems when the
result isn't a simple float (but one with an exponent). In other words,
mucking about the resulting string doesn't look like a good idea ...
Does anyone have an idea how to go about this ?
Regards,
Rudy Wieser
I don't recall what %g does, but %f will give your more than one
decimal. %.1f will constrain it to one decimal; %.2 to two,
ad lnductum.

If you want exponential notation mixed with plain old decimals,
wsprintf() to a couple of strings, one using %f and the other with
%.3f ( say ) and strstr() for (e or E) in the one with %f .
--
Les Cargill
R.Wieser
2018-05-12 07:33:11 UTC
Permalink
Les,
I don't recall what %g does, but %f will give your more than one decimal.
%.1f will constrain it to one decimal; %.2 to two,
ad lnductum.
I know. The problem with that is that I have no idea what the to-be-printed
value will be. Using %f with a fixed number of decimals might give me a
tens-of-digits integer for large numbers, or (effectivily) "0" because the
value is smaller than the fixed precision (a real-world example: 2.3
TerraByte v.s. 8 picoFarad).
... and strstr() for (e or E) in the one with %f
Thats pretty-much what I'm trying to evade: suppressing a modification* (the
adding of a ".0") when certain markers are present. Not being aware of
just a single one of those markers causes the output to be malformed by the
addition.

* I could try to do it the opposite way and check if the output is an int
and only if so apply the modification, but the same principle applies: not
being aware of a valid integer output (the sign symbols and their placement
due to localisations/preferences comes to mind) would cause the above
adition not to be applied when it should.

Hence my question of if what I'm looking for is maybe already build-in.

Regards,
Rudy Wieser
Les Cargill
2018-05-13 15:23:37 UTC
Permalink
Post by R.Wieser
Les,
I don't recall what %g does, but %f will give your more than one decimal.
%.1f will constrain it to one decimal; %.2 to two,
ad lnductum.
I know. The problem with that is that I have no idea what the to-be-printed
value will be. Using %f with a fixed number of decimals might give me a
tens-of-digits integer for large numbers, or (effectivily) "0" because the
value is smaller than the fixed precision (a real-world example: 2.3
TerraByte v.s. 8 picoFarad).
... and strstr() for (e or E) in the one with %f
Thats pretty-much what I'm trying to evade: suppressing a modification* (the
adding of a ".0") when certain markers are present. Not being aware of
just a single one of those markers causes the output to be malformed by the
addition.
* I could try to do it the opposite way and check if the output is an int
and only if so apply the modification, but the same principle applies: not
being aware of a valid integer output (the sign symbols and their placement
due to localisations/preferences comes to mind) would cause the above
adition not to be applied when it should.
Hence my question of if what I'm looking for is maybe already build-in.
Regards,
Rudy Wieser
I no longer have any firm idea of what you're trying to accomplish. At
worst, I'd have:

// in order of precedence.
char *tehFmts[] = {
"%.3f",
"%g",
...
};

int k;

#define dim(x) ( sizeof(x) / sizeof(x[0]) )

for (k=0;k<dim(tehFmts);k++)
{
wsprintf(buffer,tehFmts[k],....);
if (meetsRequirements(buffer))
{
break;
}
}

if (k == dim(tehFmts))
{
// error case
}

Good luck.
--
Les Cargill
R.Wieser
2018-05-13 17:37:47 UTC
Permalink
Les,
Post by Les Cargill
I no longer have any firm idea of what you're trying to accomplish.
Very simply put: If "%g" returns a simple float (in a %f notation) and no
decimal dot is present than append the string ".0", so it becomes clear the
value is (coming from) a float.

Examples:

When using "%g" :
The float 42.0 will be printed as just "42". Which is what my problem
started with.
The float 2,300,000,000 will be printed as "2.3e+009", which is alright
(didn't expect the "00" though)
The float 0.000008 will be printed as "8e-006", which works somewhat for me.

When using "%.3f":
The float 42.0 will be printed as "42.000", and that won't do.
The float 2,300,000,000 will be printed as "2,300,000,000.000", which also
not what I want to see
The float 0.000008 will be printed as "0.000", which would be disastrous.

What I'm after (best-case scenario, not what I initially asked):
The float 42.0 will be printed as "42.0"
The float 2,300,000,000 will be printed as "2.3e9" (but "2.3e+9" or
"2.3e+009" are acceptable too)
The float 0.000008 will be printed as "8.0e-6" (or "8.0e-006" or just
itself - same lengths: a bad example)
Post by Les Cargill
if (meetsRequirements(buffer))
That "meetsRequirements()" is exactly what is causing me trouble, and why I
want to, if possible, not do it that way.

The above "When using" examples show what *my* computer gives me, and I'm
not sure that it will be the same everywhere, nor that its a full list.

Regards,
Rudy Wieser

Loading...