Рациональные, комплексные и произвольная точность
Julia из коробки умеет точные дроби, комплексные числа и арифметику любой разрядности.
Богатая числовая система — встроенная поддержка рациональных, комплексных и сверхбольших чисел без сторонних библиотек.
Здесь Julia заметно опережает Python: то, для чего в Python нужны модули fractions, cmath или decimal, в Julia встроено в язык и работает быстро.
Рациональные числа
Дробь записывается двойной косой чертой //. Julia хранит её точно как пару «числитель/знаменатель» и автоматически сокращает:
r = 3//4
s = 1//6
sum = r + s
println(sum)
println(numerator(sum), " / ", denominator(sum))Вывод:
11//12 11 / 12
Никаких ошибок округления: 1//3 + 1//3 + 1//3 точно равно 1//1, тогда как 0.1 + 0.2 в Float уже не точно 0.3.
Комплексные числа
Мнимая единица записывается как im. Комплексные числа — полноценная часть языка:
z = 2 + 3im
println(z * (1 - 1im))
println(abs(z)) # модуль
println(real(z), " ", imag(z))Вывод:
5 + 1im 3.605551275463989 2 3
Работают и функции из математики комплексных чисел: sqrt(-1 + 0im) вернёт 0.0 + 1.0im, а не ошибку.
Произвольная точность
Когда Int64 или Float64 не хватает диапазона, используют BigInt и BigFloat. Чтобы число стало большим, оберните его в big():
f = factorial(big(30))
println(f)Вывод:
265252859812191058636308480000000
Сравните: factorial(30) с обычным Int64 переполнится и даст бессмысленный результат, а factorial(big(30)) вычислит точное значение.
Преобразование типов
Между числовыми типами есть явные и неявные преобразования. Функции Int, Float64, BigInt приводят значение к нужному типу:
println(Float64(3//4)) # 0.75
println(Int(round(3.7))) # 4Вывод:
0.75 4
Как работает под капотом
Рациональные и комплексные числа в Julia — это параметрические типы: Rational{Int64} и Complex{Float64}. То есть «дробь из целых» и «комплексное из дробных» — разные конкретные типы, но с общим шаблоном. Эта система типов (её мы разберём отдельно) позволяет компилятору генерировать быстрый специализированный код для каждой комбинации. BigInt и BigFloat опираются на библиотеки GMP и MPFR, поэтому они медленнее машинных типов — используйте их только там, где точность реально нужна.
Частые ошибки
Главная ошибка — оборачивать в big() уже переполнившийся результат. Если написать big(factorial(30)), то factorial(30) сначала переполнится в Int64, и только потом «испорченное» значение станет BigInt. Правильно оборачивать аргумент: factorial(big(30)), чтобы все вычисления шли в большой арифметике.
Итоги
- Рациональные числа (
3//4) хранятся точно, без округления. - Комплексные числа встроены: мнимая единица —
im. BigInt/BigFloatдают произвольную точность; оборачивайте вbig()исходные аргументы.- Рациональные и комплексные — параметрические типы, что обеспечивает скорость.