Formatting Floats Without Trailing Zeros

Formatting floats without trailing zeros

Me, I'd do ('%f' % x).rstrip('0').rstrip('.') -- guarantees fixed-point formatting rather than scientific notation, etc etc. Yeah, not as slick and elegant as %g, but, it works (and I don't know how to force %g to never use scientific notation;-).

Formatting a float number without trailing zeros

Thanks all for your help! The answer came from @vaultah:

>>> f'{2.1:g}'
'2.1'
>>> f'{2.0:g}'
'2'

So just use regular division such as 4/2 and then format the string.
From the docs for 'g': https://docs.python.org/2/library/string.html#format-specification-mini-language
"insignificant trailing zeros are removed from the significand, and the decimal point is also removed if there are no remaining digits following it."

Avoid trailing zeroes in printf()

This can't be done with the normal printf format specifiers. The closest you could get would be:

printf("%.6g", 359.013); // 359.013
printf("%.6g", 359.01); // 359.01

but the ".6" is the total numeric width so

printf("%.6g", 3.01357); // 3.01357

breaks it.

What you can do is to sprintf("%.20g") the number to a string buffer then manipulate the string to only have N characters past the decimal point.

Assuming your number is in the variable num, the following function will remove all but the first N decimals, then strip off the trailing zeros (and decimal point if they were all zeros).

char str[50];
sprintf (str,"%.20g",num); // Make the number.
morphNumericString (str, 3);
: :
void morphNumericString (char *s, int n) {
char *p;
int count;

p = strchr (s,'.'); // Find decimal point, if any.
if (p != NULL) {
count = n; // Adjust for more or less decimals.
while (count >= 0) { // Maximum decimals allowed.
count--;
if (*p == '\0') // If there's less than desired.
break;
p++; // Next character.
}

*p-- = '\0'; // Truncate string.
while (*p == '0') // Remove trailing zeros.
*p-- = '\0';

if (*p == '.') { // If all decimals were zeros, remove ".".
*p = '\0';
}
}
}

If you're not happy with the truncation aspect (which would turn 0.12399 into 0.123 rather than rounding it to 0.124), you can actually use the rounding facilities already provided by printf. You just need to analyse the number before-hand to dynamically create the widths, then use those to turn the number into a string:

#include <stdio.h>

void nDecimals (char *s, double d, int n) {
int sz; double d2;

// Allow for negative.

d2 = (d >= 0) ? d : -d;
sz = (d >= 0) ? 0 : 1;

// Add one for each whole digit (0.xx special case).

if (d2 < 1) sz++;
while (d2 >= 1) { d2 /= 10.0; sz++; }

// Adjust for decimal point and fractionals.

sz += 1 + n;

// Create format string then use it.

sprintf (s, "%*.*f", sz, n, d);
}

int main (void) {
char str[50];
double num[] = { 40, 359.01335, -359.00999,
359.01, 3.01357, 0.111111111, 1.1223344 };
for (int i = 0; i < sizeof(num)/sizeof(*num); i++) {
nDecimals (str, num[i], 3);
printf ("%30.20f -> %s\n", num[i], str);
}
return 0;
}

The whole point of nDecimals() in this case is to correctly work out the field widths, then format the number using a format string based on that. The test harness main() shows this in action:

  40.00000000000000000000 -> 40.000
359.01335000000000263753 -> 359.013
-359.00999000000001615263 -> -359.010
359.00999999999999090505 -> 359.010
3.01357000000000008200 -> 3.014
0.11111111099999999852 -> 0.111
1.12233439999999995429 -> 1.122

Once you have the correctly rounded value, you can once again pass that to morphNumericString() to remove trailing zeros by simply changing:

nDecimals (str, num[i], 3);

into:

nDecimals (str, num[i], 3);
morphNumericString (str, 3);

(or calling morphNumericString at the end of nDecimals but, in that case, I'd probably just combine the two into one function), and you end up with:

  40.00000000000000000000 -> 40
359.01335000000000263753 -> 359.013
-359.00999000000001615263 -> -359.01
359.00999999999999090505 -> 359.01
3.01357000000000008200 -> 3.014
0.11111111099999999852 -> 0.111
1.12233439999999995429 -> 1.122

Format a float to n decimal places and no trailing zeros

strconv.FormatFloat(10.900, 'f', -1, 64)

This will result in 10.9.

The -1 as the third parameter tells the function to print the fewest digits necessary to accurately represent the float.

See here: https://golang.org/pkg/strconv/#FormatFloat

How to format a float without trailing zeros in Rust?

This currently solves the issue for me:

let y = (x * 100_000_000.0).round() / 100_000_000.0;
format!("{}", y);

I will keep an eye out for any better solutions. Thank you!

dropping trailing '.0' from floats

(str(i)[-2:] == '.0' and str(i)[:-2] or str(i) for i in ...)

Format float with given precision ignoring trailing zeros

Assuming you mean "trailing zeroes", you can use my library float_pretty_print. It attains output similar to what you want by running standard float formatter multiple times and choosing the appropriate output. You can set minimum and maximum width.

$ cargo run --example=repl
Type number to be formatted using float_pretty_print
Also type `width=<number>` or `prec=<number>` to set width or precision.
3.1
3.1
3.12345
3.12345
prec=5
3.1
3.1
3.12345
3.123
width=5
3.1
3.100

Note that instead of precision, you set maximum width in characters of the whole output (not just the fractional).
Also do now expect high performance - the library may allocate multiple times for processing one number.

How to nicely format floating numbers to string without unnecessary decimal 0's

If the idea is to print integers stored as doubles as if they are integers, and otherwise print the doubles with the minimum necessary precision:

public static String fmt(double d)
{
if(d == (long) d)
return String.format("%d",(long)d);
else
return String.format("%s",d);
}

Produces:

232
0.18
1237875192
4.58
0
1.2345

And does not rely on string manipulation.



Related Topics



Leave a reply



Submit