-
Notifications
You must be signed in to change notification settings - Fork 8
/
bigint.jl
120 lines (110 loc) · 3.25 KB
/
bigint.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
mutability(::Type{BigInt}) = IsMutable()
mutable_copy(x::BigInt) = deepcopy(x)
# zero
promote_operation(::typeof(zero), ::Type{BigInt}) = BigInt
mutable_operate!(::typeof(zero), x::BigInt) = Base.GMP.MPZ.set_si!(x, 0)
# one
promote_operation(::typeof(one), ::Type{BigInt}) = BigInt
mutable_operate!(::typeof(one), x::BigInt) = Base.GMP.MPZ.set_si!(x, 1)
# +
promote_operation(::typeof(+), ::Vararg{Type{BigInt},N}) where {N} = BigInt
function mutable_operate_to!(output::BigInt, ::typeof(+), a::BigInt, b::BigInt)
return Base.GMP.MPZ.add!(output, a, b)
end
#function mutable_operate_to!(output::BigInt, op::typeof(+), a::BigInt, b::LinearAlgebra.UniformScaling)
# return mutable_operate_to!(output, op, a, b.λ)
#end
# -
promote_operation(::typeof(-), ::Vararg{Type{BigInt},N}) where {N} = BigInt
function mutable_operate_to!(output::BigInt, ::typeof(-), a::BigInt, b::BigInt)
return Base.GMP.MPZ.sub!(output, a, b)
end
# *
promote_operation(::typeof(*), ::Vararg{Type{BigInt},N}) where {N} = BigInt
function mutable_operate_to!(output::BigInt, ::typeof(*), a::BigInt, b::BigInt)
return Base.GMP.MPZ.mul!(output, a, b)
end
function mutable_operate_to!(
output::BigInt,
op::Union{typeof(+),typeof(-),typeof(*)},
a::BigInt,
b::BigInt,
c::Vararg{BigInt,N},
) where {N}
mutable_operate_to!(output, op, a, b)
return mutable_operate!(op, output, c...)
end
function mutable_operate!(op::Function, x::BigInt, args::Vararg{Any,N}) where {N}
mutable_operate_to!(x, op, x, args...)
end
# add_mul and sub_mul
# Buffer to hold the product
buffer_for(::AddSubMul, args::Vararg{Type{BigInt},N}) where {N} = BigInt()
function mutable_operate_to!(
output::BigInt,
op::AddSubMul,
x::BigInt,
y::BigInt,
z::BigInt,
args::Vararg{BigInt,N},
) where {N}
return mutable_buffered_operate_to!(BigInt(), output, op, x, y, z, args...)
end
function mutable_buffered_operate_to!(
buffer::BigInt,
output::BigInt,
op::AddSubMul,
a::BigInt,
x::BigInt,
y::BigInt,
args::Vararg{BigInt,N},
) where {N}
mutable_operate_to!(buffer, *, x, y, args...)
return mutable_operate_to!(output, add_sub_op(op), a, buffer)
end
function mutable_buffered_operate!(
buffer::BigInt,
op::AddSubMul,
x::BigInt,
args::Vararg{Any,N},
) where {N}
return mutable_buffered_operate_to!(buffer, x, op, x, args...)
end
function _scaling_to_bigint(x)
return convert(BigInt, scaling_to_number(x))
end
function mutable_operate_to!(
output::BigInt,
op::Union{typeof(+),typeof(-),typeof(*)},
args::Vararg{Scaling,N},
) where {N}
return mutable_operate_to!(output, op, _scaling_to_bigint.(args)...)
end
function mutable_operate_to!(
output::BigInt,
op::AddSubMul,
x::Scaling,
y::Scaling,
z::Scaling,
args::Vararg{Scaling,N},
) where {N}
return mutable_operate_to!(
output,
op,
_scaling_to_bigint(x),
_scaling_to_bigint(y),
_scaling_to_bigint(z),
_scaling_to_bigint.(args)...,
)
end
# Called for instance if `args` is `(v', v)` for a vector `v`.
function mutable_operate_to!(
output::BigInt,
op::AddSubMul,
x,
y,
z,
args::Vararg{Any,N},
) where {N}
return mutable_operate_to!(output, add_sub_op(op), x, *(y, z, args...))
end