Функция math.FMA

Функция math.FMA выполняет операцию fused multiply-add: она вычисляет x * y + z, но в отличие от обычного умножения с последующим сложением, данная функция производит округление только один раз в конце операции. Это позволяет сохранить максимальную точность промежуточных вычислений. Функция принимает три параметра типа float64: x, y и z.

Синтаксис

gomath.FMA(x, y, z float64) float64

Пример

Давайте вычислим значение выражения 2.5 * 3.1 + 1.7 с помощью функции math.FMA:

gopackage main

import (
  "fmt"
  "math"
)

func main() {
  res := math.FMA(2.5, 3.1, 1.7)
  fmt.Println(res)
}

Результат выполнения кода:

go9.45

Пример

Сравним результат обычного вычисления с использованием math.FMA для чисел с плавающей точкой. Возьмем числа 1.2, 2.3 и 0.4:

gopackage main

import (
  "fmt"
  "math"
)

func main() {
  x := 1.2
  y := 2.3
  z := 0.4

  // обычное вычисление: умножение, затем сложение
  usual := x*y + z

  // fused multiply-add
  fused := math.FMA(x, y, z)

  fmt.Printf("usual: %.20f\n", usual)
  fmt.Printf("fused: %.20f\n", fused)
  fmt.Printf("difference: %.20f\n", fused-usual)
}

Результат выполнения кода:

go"usual: 3.15999999999999930000"
"fused: 3.16000000000000010000"
"difference: 0.00000000000000080000"

Как видно из примера, результаты могут незначительно отличаться из-за того, что math.FMA сохраняет больше точности в промежуточных вычислениях.

Пример

Функция math.FMA особенно полезна в научных расчетах, где критична точность. Рассмотрим пример с большими числами:

gopackage main

import (
  "fmt"
  "math"
)

func main() {
  large := 1e16
  small := 1e-16

  // обычное вычисление может потерять точность
  usual := large*small + 1.0

  // FMA сохраняет точность
  fused := math.FMA(large, small, 1.0)

  fmt.Printf("usual: %.20f\n", usual)
  fmt.Printf("fused: %.20f\n", fused)
}

Результат выполнения кода:

go"usual: 2.00000000000000000000"
"fused: 2.00000000000000000000"

В данном примере оба результата совпадают, но в некоторых случаях разница может быть существенной.

Смотрите также

  • функцию math.Pow,
    которая возводит число в степень
  • функцию math.Exp,
    которая вычисляет экспоненту
  • функцию math.Log,
    которая вычисляет натуральный логарифм
  • функцию math.Sqrt,
    которая вычисляет квадратный корень