1

Let's say I have a series of numbers like:

"1.01", "1.2345", "321.1" etc.

I want them to present as:

"01.010" "01.2345" "321.100"

So 2 int digits and 3 float digits, but if they exceed it fine, show them all.

I looked at the fmt command options, but didn't see anything that covers minimum number of digits cleanly.

This is just for display, so number or string is fine as an end result.

tknx
  • 11
  • 1

1 Answers1

3

Formatting floats

This is simply the f verb with 3 precision, and width being 2+3+1 = 6 width (2 decimal, 3 fractional and 1 for dot), prefix it with 0 to pad with zeros, so simply print them as:

fmt.Printf("%06.3f\n", f)

Testing it:

fs := []float64{1.01, 1.2345, 321.1}
for _, f := range fs {
    fmt.Printf("%06.3f\n", f)
}

This will output (try it on the Go Playground):

01.010
01.234
321.100

If you want the result as a string (and not print it on your console), use fmt.Sprintf():

s := fmt.Sprintf("%06.3f\n", f)

Note: %06.3f will limit fractional digits to 3, and result in 01.234 instead of 01.2345. This isn't what you asked for, but I recommend to limit the fractional digits, else you get unexpected results, for example:

i := 0.1
fmt.Println(i + 0.2)

This will output:

0.30000000000000004

But if you use

fmt.Printf("%06.3f\n", i+0.2)

You will get (try it on the Go Playground):

00.300

See related questions:

Is there any standard library to convert float64 to string with fix width with maximum number of significant digits?

Golang Round to Nearest 0.05

Formatting strings

There is no ready function in the standard lib, so you have to write it yourself.

Here's a simple solution (not the fastest):

func format(s string) string {
    parts := strings.Split(s, ".")

    // Pad integer part on the left
    for len(parts[0]) < 2 {
        parts[0] = "0" + parts[0]
    }

    // Pad fractional part on the right
    if len(parts) < 2 {
        parts = append(parts, "0")
    }
    for len(parts[1]) < 3 {
        parts[1] += "0"
    }

    return strings.Join(parts, ".")
}

Testing it:

nums := []string{"1.01", "1.2345", "321.1", "2", ".4"}
for _, n := range nums {
    fmt.Println(format(n))
}

Output (try it on the Go Playground):

01.010
01.2345
321.100
02.000
00.400
icza
  • 389,944
  • 63
  • 907
  • 827
  • Thanks - but I do want to have that 3 decimals as a minimum. The use case is the numbers are manually entered anyway, so there is no chance of having weird math things happen. – tknx Jun 02 '22 at 20:05
  • @tknx So you want to format `string`s, not `float64`s. You didn't mention that. See edited answer. – icza Jun 02 '22 at 20:27