Юлия по умолчанию использует целые числа машин. Для получения дополнительной информации об этом см. FAQ: Почему Джулия использует целочисленную арифметику машинной машины? .
Короче говоря: наиболее эффективные целочисленные операции на любом современном CPU включают вычисления с фиксированным числом битов. На вашей машине это 64 бита.
julia> 9223372036854775805 + 1
9223372036854775806
julia> 9223372036854775805 + 2
9223372036854775807
julia> 9223372036854775805 + 3
-9223372036854775808
Вау! Что сейчас произошло!? Это определенно неправильно! Это более очевидно, если вы посмотрите, как эти числа представлены в двоичном виде:
julia> bitstring(9223372036854775805 + 1)
"0111111111111111111111111111111111111111111111111111111111111110"
julia> bitstring(9223372036854775805 + 2)
"0111111111111111111111111111111111111111111111111111111111111111"
julia> bitstring(9223372036854775805 + 3)
"1000000000000000000000000000000000000000000000000000000000000000"
Итак, вы можете видеть, что эти 63 бита «закончились» и перевернулись - 64-й бит называется «знаковым битом» и сигнализирует отрицательное число.
Существует два возможных решения, когда вы видите переполнение, подобное этому: вы можете использовать «проверенную арифметику» - как это делает рациональный код - это гарантирует, что у вас не возникнет эта проблема в скрытом режиме:
julia> Base.Checked.checked_add(9223372036854775805, 3)
ERROR: OverflowError: 9223372036854775805 + 3 overflowed for type Int64
Или вы можете использовать больший целочисленный тип - например, неограниченный BigInt
:
julia> big(9223372036854775805) + 3
9223372036854775808
Таким образом, простое решение - удалить аннотации типов и динамически выбирать целочисленные типы на основе limit
:
function series(limit, i=one(limit), n=one(limit)//one(limit))
while i <= limit
n = 1 + 1//(1 + 2n)
println(n)
return series(limit, i + 1, n)
end
end
julia> series(big(50))
#…
1186364911176312505629042874//926285732032534439103474303
4225301286417693889465034354//3299015554385159450361560051