Пакет math: константы, округление и математические операции

Краткое описание

Изучаем стандартный пакет math, который содержит математические константы высокой точности, функции округления, возведения в степень, извлечения корней, тригонометрические и логарифмические функции. Узнаём, как решать практические задачи с геометрией, процентами и углами. Главное: не учить наизусть, а помнить о существовании пакета для решения математических задач.

Импорт и документация

import "math"

Просмотр исходников:

  • Правая кнопка мыши → Go to Definition (F12)
  • Cmd+Click (macOS) или Ctrl+Click (Windows/Linux) по функции
  • Изучайте доступные функции и константы в документации

Ключевые концепции

1. Математические константы

Пакет math предоставляет константы с высокой точностью (15+ знаков после запятой).

import (
    "fmt"
    "math"
)

func main() {
    fmt.Printf("Pi = %.15f\n", math.Pi)       // 3.141592653589793
    fmt.Printf("E = %.15f\n", math.E)         // 2.718281828459045
    fmt.Printf("Phi = %.15f\n", math.Phi)     // 1.618033988749895 (золотое сечение)
    fmt.Printf("Sqrt2 = %.15f\n", math.Sqrt2) // 1.414213562373095
    fmt.Printf("Ln2 = %.15f\n", math.Ln2)     // 0.693147180559945
    fmt.Printf("Ln10 = %.15f\n", math.Ln10)   // 2.302585092994046
}

Наиболее часто используемые:

  • math.Pi (π) — число пи
  • math.E (e) — константа Эйлера

Остальные константы — для специфических задач (золотое сечение, логарифмы).

2. Функции округления

math.Round — математическое округление

Правило: если следующий разряд ≥ 5, округляем вверх; иначе — вниз.

fmt.Printf("Round(3.4) = %.0f\n", math.Round(3.4)) // 3
fmt.Printf("Round(3.5) = %.0f\n", math.Round(3.5)) // 4
fmt.Printf("Round(3.6) = %.0f\n", math.Round(3.6)) // 4
fmt.Printf("Round(3.7) = %.0f\n", math.Round(3.7)) // 4

math.Floor — округление вниз (к -∞)

Принцип: ближайшее целое число, меньшее или равное данному.

fmt.Printf("Floor(3.1) = %.0f\n", math.Floor(3.1))   // 3
fmt.Printf("Floor(3.9) = %.0f\n", math.Floor(3.9))   // 3
fmt.Printf("Floor(-2.3) = %.0f\n", math.Floor(-2.3)) // -3 ⚠️ (не -2!)
fmt.Printf("Floor(-2.9) = %.0f\n", math.Floor(-2.9)) // -3

Важно: для отрицательных чисел округляет к минус бесконечности.

math.Ceil — округление вверх (к +∞)

Принцип: ближайшее целое число, большее или равное данному.

fmt.Printf("Ceil(3.1) = %.0f\n", math.Ceil(3.1))   // 4
fmt.Printf("Ceil(3.9) = %.0f\n", math.Ceil(3.9))   // 4
fmt.Printf("Ceil(-2.3) = %.0f\n", math.Ceil(-2.3)) // -2 ⚠️ (не -3!)
fmt.Printf("Ceil(-2.9) = %.0f\n", math.Ceil(-2.9)) // -2

Визуализация числовой прямой:

По горизонтали: ... -3 -2 -1 0 1 2 3 ...

По вертикали (для понимания "вверх"/"вниз"):
     3
     2
     1
     0
    -1
    -2
    -3
  • Ceil (вверх): -2.5 → -2 (вверх по вертикали)
  • Floor (вниз): -2.5 → -3 (вниз по вертикали)

math.Trunc — отбрасывание дробной части

Принцип: просто удаляет дробную часть, оставляя целую.

fmt.Printf("Trunc(3.9) = %.0f\n", math.Trunc(3.9))   // 3
fmt.Printf("Trunc(-3.9) = %.0f\n", math.Trunc(-3.9)) // -3 ⚠️
fmt.Printf("Trunc(5.1) = %.0f\n", math.Trunc(5.1))   // 5

Критическое отличие Floor и Trunc:

negNum := -2.7

fmt.Printf("Floor(-2.7) = %.0f\n", math.Floor(negNum))  // -3 (округление к -∞)
fmt.Printf("Trunc(-2.7) = %.0f\n", math.Trunc(negNum))  // -2 (отбрасывание к 0)

Запомнить:

  • Floor — всегда к минус бесконечности
  • Trunc — всегда к нулю

3. Функция модуля (абсолютная величина)

math.Abs — модуль числа

Возвращает неотрицательное значение числа.

fmt.Printf("Abs(-5.5) = %.1f\n", math.Abs(-5.5)) // 5.5
fmt.Printf("Abs(5.5) = %.1f\n", math.Abs(5.5))   // 5.5
fmt.Printf("Abs(-100) = %.0f\n", math.Abs(-100)) // 100
fmt.Printf("Abs(0) = %.0f\n", math.Abs(0))       // 0

Применение:

  • Расстояния (всегда положительные)
  • Разница между числами
  • Отклонение от среднего значения

4. Степени и корни

math.Pow — возведение в степень

Формат: math.Pow(основание, показатель)

fmt.Printf("2³ = %.0f\n", math.Pow(2, 3))    // 8
fmt.Printf("5² = %.0f\n", math.Pow(5, 2))    // 25
fmt.Printf("2¹⁰ = %.0f\n", math.Pow(2, 10))  // 1024
fmt.Printf("10³ = %.0f\n", math.Pow(10, 3))  // 1000

Дробные степени = корни:

// a^0.5 = √a (квадратный корень)
fmt.Printf("4^0.5 = %.0f\n", math.Pow(4, 0.5))  // 2

// a^(1/3) = ³√a (кубический корень)
fmt.Printf("8^(1/3) = %.0f\n", math.Pow(8, 1.0/3.0))  // 2

Математическая формула:

  • √a = a^(1/2) = a^0.5
  • ³√a = a^(1/3)
  • ᵐ√(aⁿ) = a^(n/m)

math.Sqrt — квадратный корень

Специализированная функция для √x.

fmt.Printf("√9 = %.0f\n", math.Sqrt(9))     // 3
fmt.Printf("√16 = %.0f\n", math.Sqrt(16))   // 4
fmt.Printf("√2 = %.10f\n", math.Sqrt(2))    // 1.4142135624
fmt.Printf("√144 = %.0f\n", math.Sqrt(144)) // 12

Эквивалентно: math.Pow(x, 0.5), но Sqrt быстрее.

math.Cbrt — кубический корень

Специализированная функция для ³√x.

fmt.Printf("³√8 = %.0f\n", math.Cbrt(8))    // 2
fmt.Printf("³√27 = %.0f\n", math.Cbrt(27))  // 3
fmt.Printf("³√64 = %.0f\n", math.Cbrt(64))  // 4
fmt.Printf("³√-8 = %.0f\n", math.Cbrt(-8))  // -2 (работает с отрицательными!)

Преимущество: работает с отрицательными числами.

math.Pow10 — степени десятки

Специализированная функция для 10^n.

fmt.Printf("10⁰ = %.0f\n", math.Pow10(0))   // 1
fmt.Printf("10¹ = %.0f\n", math.Pow10(1))   // 10
fmt.Printf("10² = %.0f\n", math.Pow10(2))   // 100
fmt.Printf("10³ = %.0f\n", math.Pow10(3))   // 1000
fmt.Printf("10⁶ = %.0f\n", math.Pow10(6))   // 1000000

Применение: научные вычисления, форматирование больших чисел.

5. Функции Min и Max

math.Max и math.Min

Возвращают максимальное или минимальное из двух чисел.

a := 10.5
b := 20.3

fmt.Printf("Max(%.1f, %.1f) = %.1f\n", a, b, math.Max(a, b)) // 20.3
fmt.Printf("Min(%.1f, %.1f) = %.1f\n", a, b, math.Min(a, b)) // 10.5

fmt.Printf("Max(100, 50) = %.0f\n", math.Max(100, 50))     // 100
fmt.Printf("Min(-5, 5) = %.0f\n", math.Min(-5, 5))         // -5
fmt.Printf("Max(-10, -20) = %.0f\n", math.Max(-10, -20))   // -10

Ограничение: работают только с двумя числами. Для большего количества — используйте цикл.

6. Практический пример: площадь круга

Задача: вычислить площадь и длину окружности по радиусу.

Формулы:

  • Площадь: S = πr²
  • Длина окружности: L = 2πr
radius := 5.0

// Площадь круга
area := math.Pi * math.Pow(radius, 2)

// Длина окружности
circumference := 2 * math.Pi * radius

fmt.Printf("Радиус: %.1f\n", radius)
fmt.Printf("Площадь: %.2f\n", area)                     // 78.54
fmt.Printf("Длина окружности: %.2f\n", circumference)   // 31.42

Обратная задача: найти радиус по длине окружности.

L = 2πr
r = L / (2π)
length := 31.42
radius = length / (2 * math.Pi)
fmt.Printf("Радиус: %.2f\n", radius)  // 5.00

Тригонометрические функции

7. Преобразование градусов в радианы

Важно: все тригонометрические функции в Go работают с радианами, не градусами!

Формулы:

  • Радианы = Градусы × (π / 180)
  • Градусы = Радианы × (180 / π)
degrees := 45.0
radians := degrees * (math.Pi / 180.0)

fmt.Printf("%.0f° = %.10f рад\n", degrees, radians)  // 0.7853981634

Запомнить:

  • 180° = π рад
  • 90° = π/2 рад
  • 45° = π/4 рад
  • 30° = π/6 рад

8. Основные тригонометрические функции

math.Sin, math.Cos, math.Tan

angle := 45.0
angleRad := angle * (math.Pi / 180.0)

sinValue := math.Sin(angleRad)
cosValue := math.Cos(angleRad)
tanValue := math.Tan(angleRad)

fmt.Printf("Угол: %.0f° (%.4f рад)\n", angle, angleRad)
fmt.Printf("Sin(%.0f°) = %.10f\n", angle, sinValue)  // 0.7071067812
fmt.Printf("Cos(%.0f°) = %.10f\n", angle, cosValue)  // 0.7071067812
fmt.Printf("Tan(%.0f°) = %.10f\n", angle, tanValue)  // 1.0000000000

Особые значения:

Угол Sin Cos Tan
0 1 0
30° 0.5 √3/2 1/√3
45° √2/2 √2/2 1
60° √3/2 0.5 √3
90° 1 0 undefined
fmt.Printf("Sin(0°) = %.1f\n", math.Sin(0))                 // 0.0
fmt.Printf("Cos(0°) = %.1f\n", math.Cos(0))                 // 1.0
fmt.Printf("Sin(90°) = %.1f\n", math.Sin(90*math.Pi/180))   // 1.0
fmt.Printf("Cos(90°) = %.10f\n", math.Cos(90*math.Pi/180))  // ~0.0
fmt.Printf("Tan(45°) = %.1f\n", math.Tan(45*math.Pi/180))   // 1.0

9. Обратные тригонометрические функции

math.Asin, math.Acos, math.Atan

Возвращают угол в радианах по значению функции.

// Арксинус
asinValue := math.Asin(0.5)  // рад
asinDegrees := asinValue * (180.0 / math.Pi)  // градусы
fmt.Printf("Asin(0.5) = %.4f рад = %.0f°\n", asinValue, asinDegrees)  // 30°

// Арккосинус
acosValue := math.Acos(0.5)
acosDegrees := acosValue * (180.0 / math.Pi)
fmt.Printf("Acos(0.5) = %.4f рад = %.0f°\n", acosValue, acosDegrees)  // 60°

// Арктангенс
atanValue := math.Atan(1.0)
atanDegrees := atanValue * (180.0 / math.Pi)
fmt.Printf("Atan(1.0) = %.4f рад = %.0f°\n", atanValue, atanDegrees)  // 45°

10. math.Atan2 — угол по координатам

Применение: вычисление угла вектора (x, y) относительно оси X.

x := 1.0
y := 1.0

angle := math.Atan2(y, x)  // ⚠️ Порядок: Y, X
angleDegrees := angle * (180.0 / math.Pi)

fmt.Printf("Точка: (%.1f, %.1f)\n", x, y)
fmt.Printf("Угол: %.4f рад = %.0f°\n", angle, angleDegrees)  // 45°

Преимущество перед Atan:

  • Учитывает квадрант (знаки X и Y)
  • Диапазон: [-π, π] (а не [-π/2, π/2])
  • Корректно работает при x = 0

11. Гиперболические функции

math.Sinh, math.Cosh, math.Tanh

Используются в специальных инженерных и физических расчётах.

x := 1.0

fmt.Printf("Sinh(%.1f) = %.10f\n", x, math.Sinh(x))  // 1.1752011936
fmt.Printf("Cosh(%.1f) = %.10f\n", x, math.Cosh(x))  // 1.5430806348
fmt.Printf("Tanh(%.1f) = %.10f\n", x, math.Tanh(x))  // 0.7615941559

// Особые значения
fmt.Printf("Sinh(0) = %.1f\n", math.Sinh(0))  // 0.0
fmt.Printf("Cosh(0) = %.1f\n", math.Cosh(0))  // 1.0
fmt.Printf("Tanh(0) = %.1f\n", math.Tanh(0))  // 0.0

Примечание автора: использовались только в университете на физмате, в реальной разработке — крайне редко.

Экспоненциальные и логарифмические функции

12. math.Exp — экспонента (e^x)

Возводит число e в указанную степень.

fmt.Printf("e⁰ = %.1f\n", math.Exp(0))            // 1.0
fmt.Printf("e¹ = %.10f\n", math.Exp(1))           // 2.7182818285 (само число e)
fmt.Printf("e² = %.10f\n", math.Exp(2))           // 7.3890560989
fmt.Printf("e⁻¹ = %.10f\n", math.Exp(-1))         // 0.3678794412
fmt.Printf("e¹⁰ = %.2f\n", math.Exp(10))          // 22026.47

13. math.Log — натуральный логарифм (ln)

Логарифм по основанию e.

fmt.Printf("ln(1) = %.1f\n", math.Log(1))          // 0.0
fmt.Printf("ln(e) = %.10f\n", math.Log(math.E))    // 1.0000000000
fmt.Printf("ln(10) = %.10f\n", math.Log(10))       // 2.3025850930
fmt.Printf("ln(100) = %.10f\n", math.Log(100))     // 4.6051701860

Свойство: ln(e^x) = x и e^(ln(x)) = x

14. math.Log10 — десятичный логарифм (lg)

Логарифм по основанию 10.

fmt.Printf("log₁₀(1) = %.0f\n", math.Log10(1))           // 0
fmt.Printf("log₁₀(10) = %.0f\n", math.Log10(10))         // 1
fmt.Printf("log₁₀(100) = %.0f\n", math.Log10(100))       // 2
fmt.Printf("log₁₀(1000) = %.0f\n", math.Log10(1000))     // 3
fmt.Printf("log₁₀(1000000) = %.0f\n", math.Log10(1000000)) // 6

Применение: порядок числа, шкалы (децибелы, pH).

15. math.Log2 — двоичный логарифм (log₂)

Логарифм по основанию 2.

fmt.Printf("log₂(1) = %.0f\n", math.Log2(1))         // 0
fmt.Printf("log₂(2) = %.0f\n", math.Log2(2))         // 1
fmt.Printf("log₂(4) = %.0f\n", math.Log2(4))         // 2
fmt.Printf("log₂(8) = %.0f\n", math.Log2(8))         // 3
fmt.Printf("log₂(1024) = %.0f\n", math.Log2(1024))   // 10
fmt.Printf("log₂(65536) = %.0f\n", math.Log2(65536)) // 16

Применение: информатика, сложность алгоритмов, размеры данных.

16. Практический пример: сложные проценты

Формула непрерывного начисления:

A = P × e^(rt)

Где:

  • A — итоговая сумма
  • P — начальный капитал
  • r — годовая ставка (в долях, 0.05 = 5%)
  • t — время в годах
principal := 10000.0  // 10,000 руб.
rate := 0.05          // 5% годовых
time := 10.0          // 10 лет

// Непрерывное начисление
amount := principal * math.Exp(rate * time)

fmt.Printf("Начальный капитал: %.2f руб.\n", principal)
fmt.Printf("Ставка: %.1f%%\n", rate*100)
fmt.Printf("Срок: %.0f лет\n", time)
fmt.Printf("Итого: %.2f руб.\n", amount)              // 16487.21
fmt.Printf("Прибыль: %.2f руб.\n", amount-principal)  // 6487.21

// Сравнение с обычными процентами
simpleAmount := principal * math.Pow(1+rate, time)
fmt.Printf("Обычные проценты: %.2f руб.\n", simpleAmount)

Примечание автора: в реальном банковском деле формулы значительно сложнее, чем в публичном доступе.

Важные моменты

1. Не учить наизусть

Просто помните о существовании пакета math. Когда понадобятся математические функции — откройте документацию или исходники (F12).

2. База для 80% задач

Чаще всего нужны:

  • Константы: math.Pi, math.E
  • Округление: math.Round, math.Floor, math.Ceil, math.Trunc
  • Модуль: math.Abs
  • Степени/корни: math.Pow, math.Sqrt
  • Min/Max: math.Min, math.Max

3. Floor vs Trunc для отрицательных

x := -2.7
fmt.Println(math.Floor(x))  // -3 (к -∞)
fmt.Println(math.Trunc(x))  // -2 (к 0)

Практика: потренируйте эту разницу самостоятельно!

4. Радианы, не градусы

Все тригонометрические функции работают с радианами. Не забывайте конвертировать:

radians = degrees * (math.Pi / 180)

5. Квадратный корень через степень

math.Sqrt(x)      // Быстрее
math.Pow(x, 0.5)  // То же самое, но медленнее

Используйте Sqrt — она оптимизирована.

6. Atan2 вместо Atan

Для вычисления угла по координатам используйте math.Atan2(y, x) — учитывает квадрант.

7. Специальные функции редко нужны

Гиперболические, обратные тригонометрические — для специфических задач (физика, инженерия). В web/backend-разработке почти не используются.

Best Practices

1. Используйте константы вместо литералов

// Хорошо
area := math.Pi * r * r

// Плохо (неточно)
area := 3.14 * r * r

2. Выбирайте правильное округление

// Для отображения (обычное округление)
displayed := math.Round(value)

// Для финансов (всегда вниз или всегда вверх)
floor := math.Floor(value)
ceil := math.Ceil(value)

// Для целой части (без округления)
integer := math.Trunc(value)

3. Конвертируйте градусы явно

// Хорошо — понятно, что конвертируем
const degreesToRadians = math.Pi / 180
angleRad := angleDeg * degreesToRadians

// Или вспомогательная функция
func toRadians(deg float64) float64 {
    return deg * (math.Pi / 180)
}

4. Документируйте математические формулы

// Площадь круга: S = πr²
area := math.Pi * math.Pow(radius, 2)

// Формула Герона для площади треугольника
// S = √(p(p-a)(p-b)(p-c)), где p = (a+b+c)/2
p := (a + b + c) / 2
area := math.Sqrt(p * (p - a) * (p - b) * (p - c))

5. Проверяйте корректность входных данных

// Квадратный корень только из неотрицательных
if x < 0 {
    return 0, errors.New("cannot calculate sqrt of negative number")
}
result := math.Sqrt(x)

// Логарифм только из положительных
if x <= 0 {
    return 0, errors.New("logarithm undefined for non-positive numbers")
}
result := math.Log(x)

Что запомнить

  • Импорт: import "math"
  • Не учить наизусть — помнить о существовании пакета
  • База (80% задач): Pi, E, Round, Floor, Ceil, Trunc, Abs, Pow, Sqrt, Min, Max
  • Floor → к минус бесконечности, Trunc → к нулю
  • Все триг. функции работают с радианами: рад = град × (π/180)
  • math.Sqrt(x) быстрее чем math.Pow(x, 0.5)
  • Формулы: √a = a^0.5, ³√a = a^(1/3), ᵐ√(aⁿ) = a^(n/m)
  • Atan2(y, x) для углов по координатам (учитывает квадрант)
  • Exp(x) = e^x, Log(x) = ln(x), Log10(x) = lg(x), Log2(x) = log₂(x)
  • Гиперболические функции — для специфических задач
  • Площадь круга: S = πr², длина окружности: L = 2πr
  • Сложные проценты: A = P × e^(rt)
  • Просмотр исходников: F12 или Cmd/Ctrl+Click

Полезные ссылки