Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
Data Types  ›  Lesson

Floating Points and Complex Numbers

Floating Points 14 minfloat64 is Go's default for fractional numbers and stores most decimals only approximately, and complex128 stores a real and an imaginary float64 part together.

Floating Points and Complex Numbers

tally wants to report "average words per line". With 17 words over 4 lines the answer should be 4.25, but the first version prints 4. Fractions need floating-point numbers, and floats come with a couple of surprises worth knowing in advance.

The rule

Fractions need float64, and float64 is close, not exact.

Go has float32 and float64. A literal with a decimal point, such as x := 4.25, is float64, and that is the one to use unless memory is truly tight.

Getting a fraction. Dividing two ints is integer division, so convert before you divide:

total, lines := 17, 4
fmt.Println(total / lines)                   // 4
fmt.Println(float64(total) / float64(lines)) // 4.25
fmt.Println(float64(total / lines))          // 4, divided too early

Close, not exact. Floats are stored in binary, and most decimals, like 0.1, have no exact binary form:

a, b := 0.1, 0.2
fmt.Println(a + b)        // 0.30000000000000004
fmt.Println(a+b == 0.3)   // false

Compare computed floats with a tolerance: math.Abs(x-y) < 1e-9. One twist: untyped constants are exact, so fmt.Println(0.1+0.2 == 0.3) with plain literals prints true. The rounding only appears once values live in float64 variables.

No crash on division by zero. A float divided by a zero float variable gives +Inf (or -Inf), and 0/0 gives NaN, which is not even equal to itself. Integer division by a zero variable, in contrast, panics.

Complex numbers are built in: complex128 (two float64s) and complex64.

c := 3 + 4i
fmt.Println(c)           // (3+4i)
fmt.Println(real(c))     // 3
fmt.Println(imag(c))     // 4
fmt.Println(cmplx.Abs(c)) // 5, from math/cmplx

You will rarely need them outside signal processing or maths, but they follow the same float rules.

The shortcut

Before any division, ask "do I want a fraction?" If yes, convert first, divide second. Before any == on floats, ask "were these computed?" If yes, compare within a tolerance.

Fixing tally's averageStep 1 of 4
  1. Spot the division

    total / lines — both ints, so the fraction is lost.

Drills

Answer fast — trust the rule.

quick drill

What is the type of r := 2.5?

quick drill

total, lines := 17, 4. What does float64(total / lines) give?

quick drill

a, b := 0.1, 0.2. What does fmt.Println(a+b == 0.3) print?

quick drill

c := 3 + 4i. What is imag(c)?

quick drill

x, zero := 1.0, 0.0. What does fmt.Println(x / zero) print?

Remember

  • Fractions need float64, and float64 is close, not exact.
  • Shortcut: convert first, divide second; compare computed floats within a tolerance.
  • Trap: float64(a / b) on ints is too late — the fraction is already gone.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainThe average that came out whole

tally prints 'average words per line' as total / lines with total 17 and lines 4, and it shows 4. Explain why, how to get 4.25, and why a test that checks avg == 4.1 style values with == on computed floats is risky.