Gavriel
Gavriel

Reputation: 19237

How to format float to omit zeros at the end of the fraction

I'd like to format a float so that it has at most 3 fractional digits, but if the last fractional digit(s) are 0 then omit them.

input : expected output
1.1234 : 1.123
1.120 : 1.12
1.100 : 1.1
1.0 : 1

The language doesn't matter as long as it uses the standard formatting C strings, i.e: "%.3f"

The solution I came up with:

function formatShortFloat(value as Float) as String {
    var str = value.format("%.3f");
    var chars = str.toCharArray();
    var end;
    for (end = str.length() - 1; chars[end] == '0' && end > 0; --end) {
    }
    if (chars[end] == '.') {
        --end;
    }
    return str.substring(0, end + 1) as String;
}

or (note, this is Monkey C, there's no easier way to access a char of a string, but that's my problem, that's why I asked for "any language", even pseudo code):

function formatShortFloat(value as Float) as String {
    var str = value.format("%.3f");
    var end = str.length();
    var lastChar;
    do {
        lastChar = str.substring(end - 1, end);
        --end;
    } while ("0".equals(lastChar));
    if (".".equals(lastChar)) {
        --end;
    }
    return str.substring(0, end + 1) as String;
}

Upvotes: 0

Views: 116

Answers (1)

chtz
chtz

Reputation: 18827

Assuming you always want 3 fractional digits (unless they are zero) and your format-function is compatible with C99 printf/sprintf, you can use the %.*g formatter and provide the number of desired total digits as an extra argument. Assuming your input numbers are not smaller than 0.001 the number you need to pass is (int)(log10(x)+4.0). If smaller values occur, I would suggest to manually return "+/-0.001" or "0" depending on x.

Proof-of-concept (in C with some debugging output for comparison -- you can just remove everything starting from \t and the extra x):

void println(double x)
{
    printf("%.*g\t= %.99g\n", (int)(log10(fabs(x))+4.0), x, x);
}

Godbolt-Demo with some test cases: https://godbolt.org/z/zsxns4h9v

Upvotes: 1

Related Questions