DevGang
Авторизоваться

Big Int в Go: работа с большими числами

Иногда нам нужно выполнять математические операции, которые включают в себя очень большие целочисленные вычисления, выходящие за пределы всех доступных примитивных типов данных. Например, факториал 100 содержит 158 цифр, поэтому мы не можем сохранить его ни в одном доступном примитивном типе данных. Golang не проверяет переполнение неявно, поэтому это может привести к неожиданным результатам, если в int64 хранится число, превышающее 64 бита.

Для решения этой проблемы Go предоставляет пакет «big», который реализует арифметику произвольной точности (большие числа).

Описание

Поддерживаются следующие числовые типы:

Int    signed integers
Rat    rational numbers
Float  floating-point numbers

Нулевое значение для Int, Rat или Float соответствует 0. Таким образом, новые значения могут быть объявлены обычными способами и обозначать 0 без дальнейшей инициализации:

var x Int        // &x is an *Int of value 0
var r = &Rat{}   // r is a *Rat of value 0
y := new(Float)  // y is a *Float of value 0

Фабричные функции

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

func NewT(v V) *T

Например, NewInt(x) возвращает *Int, установленный в значение аргумента x int64, NewRat(a, b) возвращает *Rat, установленный в дроби a/b, где a и b - значения int64, а NewFloat(f) возвращает *Float, инициализированный аргументом f float64. Большая гибкость обеспечивается явными сеттерами, например:

var z1 Int
z1.SetUint64(123)                 // z1 := 123
z2 := new(Rat).SetFloat64(1.25)   // z2 := 5/4
z3 := new(Float).SetInt(z1)       // z3 := 123.0

Использование: число Фибоначчи

Теперь давайте рассмотрим пример.

В этом примере показано, как использовать big.Int для вычисления наименьшего числа Фибоначчи со 100 десятичными знаками и для проверки того, является ли оно простым. Это дает обзор использования большого пакета.

Преобразование в другие типы и обратно

Другая трудность, с которой я сталкиваюсь при работе с пакетом big - это преобразование типов. Преобразование типов - это то, что мы делаем регулярно, когда пишем код для разработки приложений.

Данные, доступные нам для использования в качестве входных данных для пакета big, часто являются примитивными типами данных. Самый простой способ - передать эти данные в строковом формате, обычно как свойства некоторого объекта JSON. Вот несколько примеров преобразования значений в и из big.Int.

Преобразование из int

Преобразовать int в big.Int просто, но вы обязательно должны передать int64, например:

newBigInt := big.newInt(int64(someInt))

Преобразование в int

Чтобы преобразовать большое целое число в uint64, запустите этот код:

var smallnum, _ = new(big.Int).SetString("2188824200011112223", 10)
num := smallnum.Uint64()

Обратите внимание, что Go не выполняет проверку границ - если значение большого целого не помещается в uint64, вы не получите никакого предупреждения, а num будет переполняться и содержать неправильное значение.

Преобразование из строки

Предполагая, что вы храните большое целое число как string, вы создаете big.Int следующим образом:

var bignum, ok = new(big.Int).SetString("218882428714186575617", 0)

Если передаваемая строка в setString() начинается с «0x», будет использоваться основание 16 (шестнадцатеричное). Если строка начинается с «0», будет использоваться восьмеричная система счисления. В противном случае будет использоваться основание 10 (десятичное). Также можно указать базу вручную (до 62). Возвращаемое значение имеет тип *big.Int. Если Go не удается создать big.Int, для ok устанавливается значение false.

Преобразование в строку

Преобразование в строку позволяет сериализовать данные как JSON, выводить на консоль и т.д., поэтому это очень полезно.

Чтобы преобразовать big.Int к string в шестнадцатеричном виде, используйте:

str1 := prime1.Text(16) // or: str1 := fmt.Sprintf("0x%x", bigInt)

Чтобы преобразовать в десятичную систему счисления, используйте:

str1 := prime1.Text(10) // fmt.Sprintf("%v", bigInt)
#Golang
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

В подарок 100$ на счет при регистрации

Получить