Тип big.Rat
Тип big.Rat представляет собой рациональное число в виде дроби p/q,
где p и q - целые числа, а q не равно нулю. Он позволяет выполнять
арифметические операции с числами любой точности без потери точности,
что особенно важно при работе с дробными значениями, где требуется
высокая точность вычислений. В отличие от float64, big.Rat
не подвержен ошибкам округления при выполнении операций деления.
Создание и инициализация
Для создания нового рационального числа используется функция
big.NewRat. Она принимает два параметра: числитель (a) и знаменатель (b).
Число представляется в виде a/b.
package main
import (
"fmt"
"math/big"
)
func main() {
r := big.NewRat(3, 4)
fmt.Println(r)
}
Результат выполнения кода:
3/4
Также можно создать нулевое рациональное число с помощью
new(big.Rat), которое представляет собой 0/1.
package main
import (
"fmt"
"math/big"
)
func main() {
r := new(big.Rat)
fmt.Println(r)
}
Результат выполнения кода:
0/1
Для установки значения из строки используется метод SetString.
Он принимает строку в формате "a/b" и возвращает само число, а также
булево значение, указывающее на успешность разбора.
package main
import (
"fmt"
"math/big"
)
func main() {
r := new(big.Rat)
_, ok := r.SetString("5/8")
if ok {
fmt.Println(r)
}
}
Результат выполнения кода:
5/8
Метод SetFrac позволяет установить значение рационального числа
из двух целых чисел big.Int, представляющих числитель и знаменатель.
package main
import (
"fmt"
"math/big"
)
func main() {
num := big.NewInt(7)
den := big.NewInt(12)
r := new(big.Rat).SetFrac(num, den)
fmt.Println(r)
}
Результат выполнения кода:
7/12
Метод SetFloat64 создает рациональное число из значения типа
float64. Он возвращает булево значение, указывающее на то,
было ли преобразование точным.
package main
import (
"fmt"
"math/big"
)
func main() {
r := new(big.Rat)
ok := r.SetFloat64(0.375)
if ok {
fmt.Println(r)
}
}
Результат выполнения кода:
3/8
Арифметические операции
Тип big.Rat поддерживает основные арифметические операции:
сложение, вычитание, умножение и деление. Все методы изменяют
приемник и возвращают его же.
package main
import (
"fmt"
"math/big"
)
func main() {
r1 := big.NewRat(1, 3)
r2 := big.NewRat(1, 6)
sum := new(big.Rat).Add(r1, r2)
diff := new(big.Rat).Sub(r1, r2)
prod := new(big.Rat).Mul(r1, r2)
quot := new(big.Rat).Quo(r1, r2)
fmt.Println("Sum:", sum)
fmt.Println("Difference:", diff)
fmt.Println("Product:", prod)
fmt.Println("Quotient:", quot)
}
Результат выполнения кода:
"Sum: 1/2"
"Difference: 1/6"
"Product: 1/18"
"Quotient: 2/1"
Сравнение чисел
Для сравнения двух рациональных чисел используется метод Cmp.
Он возвращает -1, если число меньше аргумента; 0, если они равны;
и 1, если число больше аргумента.
package main
import (
"fmt"
"math/big"
)
func main() {
r1 := big.NewRat(2, 5)
r2 := big.NewRat(3, 7)
cmp := r1.Cmp(r2)
if cmp < 0 {
fmt.Println("r1 < r2")
} else if cmp == 0 {
fmt.Println("r1 == r2")
} else {
fmt.Println("r1 > r2")
}
}
Результат выполнения кода:
"r1 < r2"
Преобразование в другие типы
Метод FloatString преобразует рациональное число в строку
с плавающей точкой с указанным количеством знаков после запятой.
package main
import (
"fmt"
"math/big"
)
func main() {
r := big.NewRat(22, 7)
fmt.Println(r.FloatString(5))
}
Результат выполнения кода:
"3.14286"
Метод Float64 возвращает приближенное значение типа
float64. Второе возвращаемое значение указывает,
является ли преобразование точным.
package main
import (
"fmt"
"math/big"
)
func main() {
r := big.NewRat(1, 3)
val, exact := r.Float64()
fmt.Printf("Value: %f, Exact: %t\n", val, exact)
}
Результат выполнения кода:
"Value: 0.333333, Exact: false"
Получение числителя и знаменателя
Методы Num и Denom возвращают числитель и знаменатель
рационального числа в виде указателей на big.Int.
package main
import (
"fmt"
"math/big"
)
func main() {
r := big.NewRat(15, 20)
num := r.Num()
den := r.Denom()
fmt.Println("Numerator:", num)
fmt.Println("Denominator:", den)
}
Результат выполнения кода:
"Numerator: 15"
"Denominator: 20"
Обратите внимание, что методы Num и Denom возвращают
некопированные внутренние значения. Изменение их влияет на исходное
рациональное число, поэтому будьте осторожны при их использовании.
Пример практического применения
Рассмотрим пример вычисления суммы дробей с последующим сокращением результата:
package main
import (
"fmt"
"math/big"
)
func main() {
r1 := big.NewRat(2, 3)
r2 := big.NewRat(3, 4)
r3 := big.NewRat(5, 6)
sum := new(big.Rat).Add(r1, r2)
sum.Add(sum, r3)
fmt.Println("Sum:", sum)
fmt.Println("Float:", sum.FloatString(3))
}
Результат выполнения кода:
"Sum: 9/4"
"Float: 2.250"
Смотрите также
-
тип
big.Float,
который представляет числа с плавающей точкой произвольной точности -
тип
big.Int,
который представляет целые числа произвольной точности -
функцию
big.NewRat,
которая создает новое рациональное число из числителя и знаменателя -
метод
big.Rat.SetFrac,
который устанавливает значение рационального числа из двух целых чисел