How to print a number with a thousand separator as spaces in Go

1 Answer

0 votes
package main

import (
    "fmt"
    "strconv"
)

/*
    Program: Print numbers with a thousand separator as spaces in Go.

    Architecture notes:
    -------------------
    - Go's fmt package does not support custom thousand separators.
    - We implement a manual formatter:
        * Convert the number to a string.
        * Handle negative numbers cleanly.
        * Insert spaces every three digits from the left.
    - The function is modular, reusable, and efficient.

    Performance notes:
    ------------------
    - O(n) time where n is the number of digits.
    - Memory usage is minimal; only small strings are created.
    - No external libraries; uses only standard Go features.

    Pitfalls:
    ---------
    - Must preserve the minus sign for negative numbers.
    - Must ensure correct grouping even for very large integers.
    - Avoid formatting floats unless converted to integers first.

    Security notes:
    ---------------
    - No external input parsing; safe for demonstration.
    - Avoid printing sensitive values in real systems.

    Tests:
    ------
    - Positive numbers
    - Negative numbers
    - Zero
    - Very large integers
*/


// FormatWithSpaces formats an integer using spaces as thousand separators.
func FormatWithSpaces(n int64) string {
    // Convert number to string
    s := strconv.FormatInt(n, 10)

    // Handle negative numbers
    isNegative := s[0] == '-'
    digits := s
    if isNegative {
        digits = s[1:]
    }

    // Determine how many digits before the first space
    lenDigits := len(digits)
    firstGroup := lenDigits % 3
    if firstGroup == 0 {
        firstGroup = 3
    }

    // Build result
    result := ""
    if isNegative {
        result = "-"
    }

    // First group
    result += digits[:firstGroup]

    // Remaining groups
    pos := firstGroup
    for pos < lenDigits {
        result += " " + digits[pos:pos+3]
        pos += 3
    }

    return result
}


func main() {
    tests := []int64{
        0,
        42,
        1234,
        987654321,
        -1234567,
        1000000000000000000, // 10^18
    }

    fmt.Println("Running test cases:\n")

    for _, n := range tests {
        fmt.Println("Original: ", n)
        fmt.Println("Formatted:", FormatWithSpaces(n), "\n")
    }
}



/*
run:

Running test cases:

Original:  0
Formatted: 0 

Original:  42
Formatted: 42 

Original:  1234
Formatted: 1 234 

Original:  987654321
Formatted: 987 654 321 

Original:  -1234567
Formatted: -1 234 567 

Original:  1000000000000000000
Formatted: 1 000 000 000 000 000 000 

*/

 



answered Sep 22 by avibootz
...