A part of some of my packages have really large integer constants saved in them (reference to one page). These constants need to be stored at the highest precision possible, and then changed to a type T
that a user requests. For very large constants, I use a form of
T(parse(BigInt,"...")//parse(BigInt,"..."))
to store the constants. This is okay when wanting high accuracy. However, the problem comes in when handling 32-bit installations. For those, the constants are not too reasonably large, but which will overflow are ones like this:
T(7828594302389//382182512025600)
However, if I change everything where the amount of digits can cause overflow to the parse(...)
syntax, then the constants no longer inline:
function f()
parse(Int64,"10000")
end
function g()
10000
end
@code_llvm f()
@code_llvm g()
julia> @code_llvm f()
; Function Attrs: uwtable
define i64 @julia_f_61160() #0 {
top:
%0 = call i64 @jlsys_parse_35934(%jl_value_t* inttoptr (i64 2147419568 to %jl_value_t*), %jl_value_t* inttoptr (i64 2228250560 to %jl_value_t*))
ret i64 %0
}
julia> @code_llvm g()
; Function Attrs: uwtable
define i64 @julia_g_61170() #0 {
top:
ret i64 10000
}
with
julia> @code_llvm parse(Int64,"100000")
; Function Attrs: uwtable
define i64 @jlsys_parse_35934(%jl_value_t*, %jl_value_t*) #0 {
top:
%2 = alloca %Nullable.5, align 8
%3 = call i64 @jlsys_endof_50451(%jl_value_t* %1)
call void @jlsys_tryparse_internal_35940(%Nullable.5* nonnull sret %2, %jl_value_t* inttoptr (i64 2147419568 to %jl_value_t*), %jl_value_t* %1, i64 1, i64 %3, i64 0, i8 1)
%4 = getelementptr inbounds %Nullable.5, %Nullable.5* %2, i64 0, i32 0
%5 = load i8, i8* %4, align 8
%6 = and i8 %5, 1
%7 = icmp eq i8 %6, 0
br i1 %7, label %if, label %L7
if: ; preds = %top
call void @jl_throw(%jl_value_t* inttoptr (i64 2160411152 to %jl_value_t*))
unreachable
L7: ; preds = %top
%8 = getelementptr i8, i8* %4, i64 8
%9 = bitcast i8* %8 to i64*
%10 = load i64, i64* %9, align 8
ret i64 %10
}
This performance hit may be very small “for most nontrivial problems”, but I would still like to not have any even minor dent in 64-bit performance due to 32-bit compatibility. However, I assume that like BigFloat
, Int64(7828594302389)
would overflow before the conversion, and so I don’t know of a nice way to handle this.