Skip to content

Commit

Permalink
primitive_ui_check
Browse files Browse the repository at this point in the history
  • Loading branch information
HertzDevil committed Oct 30, 2023
1 parent 75c4a9d commit d4cea5f
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 45 deletions.
72 changes: 36 additions & 36 deletions src/big/big_int.cr
Original file line number Diff line number Diff line change
Expand Up @@ -166,9 +166,9 @@ struct BigInt < Int
def +(other : Int) : BigInt
Int.primitive_ui_check(other) do |ui, neg_ui, big_i|
{
BigInt.new { |mpz| LibGMP.add_ui(mpz, self, {{ ui }}) },
BigInt.new { |mpz| LibGMP.sub_ui(mpz, self, {{ neg_ui }}) },
self + {{ big_i }},
ui: BigInt.new { |mpz| LibGMP.add_ui(mpz, self, {{ ui }}) },
neg_ui: BigInt.new { |mpz| LibGMP.sub_ui(mpz, self, {{ neg_ui }}) },
big_i: self + {{ big_i }},
}
end
end
Expand All @@ -184,9 +184,9 @@ struct BigInt < Int
def -(other : Int) : BigInt
Int.primitive_ui_check(other) do |ui, neg_ui, big_i|
{
BigInt.new { |mpz| LibGMP.sub_ui(mpz, self, {{ ui }}) },
BigInt.new { |mpz| LibGMP.add_ui(mpz, self, {{ neg_ui }}) },
self - {{ big_i }},
ui: BigInt.new { |mpz| LibGMP.sub_ui(mpz, self, {{ ui }}) },
neg_ui: BigInt.new { |mpz| LibGMP.add_ui(mpz, self, {{ neg_ui }}) },
big_i: self - {{ big_i }},
}
end
end
Expand Down Expand Up @@ -253,9 +253,9 @@ struct BigInt < Int
def unsafe_floored_div(other : Int) : BigInt
Int.primitive_ui_check(other) do |ui, neg_ui, big_i|
{
BigInt.new { |mpz| LibGMP.fdiv_q_ui(mpz, self, {{ ui }}) },
BigInt.new { |mpz| LibGMP.fdiv_q_ui(mpz, -self, {{ neg_ui }}) },
unsafe_floored_div({{ big_i }}),
ui: BigInt.new { |mpz| LibGMP.fdiv_q_ui(mpz, self, {{ ui }}) },
neg_ui: BigInt.new { |mpz| LibGMP.fdiv_q_ui(mpz, -self, {{ neg_ui }}) },
big_i: unsafe_floored_div({{ big_i }}),
}
end
end
Expand All @@ -267,9 +267,9 @@ struct BigInt < Int
def unsafe_truncated_div(other : Int) : BigInt
Int.primitive_ui_check(other) do |ui, neg_ui, big_i|
{
BigInt.new { |mpz| LibGMP.tdiv_q_ui(mpz, self, {{ ui }}) },
BigInt.new { |mpz| LibGMP.tdiv_q_ui(mpz, self, {{ neg_ui }}); LibGMP.neg(mpz, mpz) },
unsafe_truncated_div({{ big_i }}),
ui: BigInt.new { |mpz| LibGMP.tdiv_q_ui(mpz, self, {{ ui }}) },
neg_ui: BigInt.new { |mpz| LibGMP.tdiv_q_ui(mpz, self, {{ neg_ui }}); LibGMP.neg(mpz, mpz) },
big_i: unsafe_truncated_div({{ big_i }}),
}
end
end
Expand Down Expand Up @@ -299,9 +299,9 @@ struct BigInt < Int
def unsafe_floored_mod(other : Int) : BigInt
Int.primitive_ui_check(other) do |ui, neg_ui, big_i|
{
BigInt.new { |mpz| LibGMP.fdiv_r_ui(mpz, self, {{ ui }}) },
BigInt.new { |mpz| LibGMP.fdiv_r_ui(mpz, self, {{ neg_ui }}); LibGMP.neg(mpz, mpz) },
unsafe_floored_mod({{ big_i }}),
ui: BigInt.new { |mpz| LibGMP.fdiv_r_ui(mpz, self, {{ ui }}) },
neg_ui: BigInt.new { |mpz| LibGMP.fdiv_r_ui(mpz, self, {{ neg_ui }}); LibGMP.neg(mpz, mpz) },
big_i: unsafe_floored_mod({{ big_i }}),
}
end
end
Expand All @@ -313,9 +313,9 @@ struct BigInt < Int
def unsafe_truncated_mod(other : Int) : BigInt
Int.primitive_ui_check(other) do |ui, neg_ui, big_i|
{
BigInt.new { |mpz| LibGMP.tdiv_r_ui(mpz, self, {{ ui }}) },
BigInt.new { |mpz| LibGMP.tdiv_r_ui(mpz, self, {{ neg_ui }}) },
unsafe_truncated_mod({{ big_i }}),
ui: BigInt.new { |mpz| LibGMP.tdiv_r_ui(mpz, self, {{ ui }}) },
neg_ui: BigInt.new { |mpz| LibGMP.tdiv_r_ui(mpz, self, {{ neg_ui }}) },
big_i: unsafe_truncated_mod({{ big_i }}),
}
end
end
Expand All @@ -330,9 +330,9 @@ struct BigInt < Int
the_q = BigInt.new
the_r = Int.primitive_ui_check(number) do |ui, neg_ui, big_i|
{
BigInt.new { |r| LibGMP.fdiv_qr_ui(the_q, r, self, {{ ui }}) },
BigInt.new { |r| LibGMP.fdiv_qr_ui(the_q, r, -self, {{ neg_ui }}); LibGMP.neg(r, r) },
BigInt.new { |r| LibGMP.fdiv_qr(the_q, r, self, {{ big_i }}) },
ui: BigInt.new { |r| LibGMP.fdiv_qr_ui(the_q, r, self, {{ ui }}) },
neg_ui: BigInt.new { |r| LibGMP.fdiv_qr_ui(the_q, r, -self, {{ neg_ui }}); LibGMP.neg(r, r) },
big_i: BigInt.new { |r| LibGMP.fdiv_qr(the_q, r, self, {{ big_i }}) },
}
end
{the_q, the_r}
Expand All @@ -348,9 +348,9 @@ struct BigInt < Int
the_q = BigInt.new
the_r = Int.primitive_ui_check(number) do |ui, neg_ui, big_i|
{
BigInt.new { |r| LibGMP.tdiv_qr_ui(the_q, r, self, {{ ui }}) },
BigInt.new { |r| LibGMP.tdiv_qr_ui(the_q, r, self, {{ neg_ui }}); LibGMP.neg(the_q, the_q) },
BigInt.new { |r| LibGMP.tdiv_qr(the_q, r, self, {{ big_i }}) },
ui: BigInt.new { |r| LibGMP.tdiv_qr_ui(the_q, r, self, {{ ui }}) },
neg_ui: BigInt.new { |r| LibGMP.tdiv_qr_ui(the_q, r, self, {{ neg_ui }}); LibGMP.neg(the_q, the_q) },
big_i: BigInt.new { |r| LibGMP.tdiv_qr(the_q, r, self, {{ big_i }}) },
}
end
{the_q, the_r}
Expand All @@ -363,9 +363,9 @@ struct BigInt < Int
def divisible_by?(number : Int) : Bool
Int.primitive_ui_check(number) do |ui, neg_ui, big_i|
{
LibGMP.divisible_ui_p(self, {{ ui }}) != 0,
LibGMP.divisible_ui_p(self, {{ neg_ui }}) != 0,
divisible_by?({{ big_i }}),
ui: LibGMP.divisible_ui_p(self, {{ ui }}) != 0,
neg_ui: LibGMP.divisible_ui_p(self, {{ neg_ui }}) != 0,
big_i: divisible_by?({{ big_i }}),
}
end
end
Expand Down Expand Up @@ -431,15 +431,15 @@ struct BigInt < Int
def gcd(other : Int) : Int
Int.primitive_ui_check(other) do |ui, neg_ui, big_i|
{
begin
ui: begin
result = LibGMP.gcd_ui(nil, self, {{ ui }})
result == 0 ? self : result
end,
begin
neg_ui: begin
result = LibGMP.gcd_ui(nil, self, {{ neg_ui }})
result == 0 ? self : result
end,
gcd({{ big_i }}),
big_i: gcd({{ big_i }}),
}
end
end
Expand All @@ -453,9 +453,9 @@ struct BigInt < Int
def lcm(other : Int) : BigInt
Int.primitive_ui_check(other) do |ui, neg_ui, big_i|
{
BigInt.new { |mpz| LibGMP.lcm_ui(mpz, self, {{ ui }}) },
BigInt.new { |mpz| LibGMP.lcm_ui(mpz, self, {{ neg_ui }}) },
lcm({{ big_i }}),
ui: BigInt.new { |mpz| LibGMP.lcm_ui(mpz, self, {{ ui }}) },
neg_ui: BigInt.new { |mpz| LibGMP.lcm_ui(mpz, self, {{ neg_ui }}) },
big_i: lcm({{ big_i }}),
}
end
end
Expand Down Expand Up @@ -808,9 +808,9 @@ struct Int
def -(other : BigInt) : BigInt
Int.primitive_ui_check(self) do |ui, neg_ui, big_i|
{
BigInt.new { |mpz| LibGMP.neg(mpz, other); LibGMP.add_ui(mpz, mpz, {{ ui }}) },
BigInt.new { |mpz| LibGMP.neg(mpz, other); LibGMP.sub_ui(mpz, mpz, {{ neg_ui }}) },
{{ big_i }} - other,
ui: BigInt.new { |mpz| LibGMP.neg(mpz, other); LibGMP.add_ui(mpz, mpz, {{ ui }}) },
neg_ui: BigInt.new { |mpz| LibGMP.neg(mpz, other); LibGMP.sub_ui(mpz, mpz, {{ neg_ui }}) },
big_i: {{ big_i }} - other,
}
end
end
Expand Down
19 changes: 10 additions & 9 deletions src/big/number.cr
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ struct BigFloat
raise DivisionByZeroError.new if other == 0
Int.primitive_ui_check(other) do |ui, neg_ui, _|
{
BigFloat.new { |mpf| LibGMP.mpf_div_ui(mpf, self, {{ ui }}) },
BigFloat.new { |mpf| LibGMP.mpf_div_ui(mpf, self, {{ neg_ui }}); LibGMP.mpf_neg(mpf, mpf) },
BigFloat.new { |mpf| LibGMP.mpf_div(mpf, self, BigFloat.new(other)) },
ui: BigFloat.new { |mpf| LibGMP.mpf_div_ui(mpf, self, {{ ui }}) },
neg_ui: BigFloat.new { |mpf| LibGMP.mpf_div_ui(mpf, self, {{ neg_ui }}); LibGMP.mpf_neg(mpf, mpf) },
big_i: BigFloat.new { |mpf| LibGMP.mpf_div(mpf, self, BigFloat.new(other)) },
}
end
end
Expand Down Expand Up @@ -67,9 +67,10 @@ struct Int
# respectively. These expressions are not evaluated unless they are
# interpolated in *block*.
#
# *block* should return a 3-tuple: the first element is returned by the macro
# if *var* fits into a `LibGMP::UI`, the second returned if the negative of
# *var* fits into a `LibGMP::UI`, and the third otherwise.
# *block* should return a named tuple: the value for `:ui` is returned by the
# macro if *var* fits into a `LibGMP::UI`, the value for `:neg_ui` returned if
# the negative of *var* fits into a `LibGMP::UI`, and the value for `:big_i`
# otherwise.
macro primitive_ui_check(var, &block)
{%
exps = yield(
Expand All @@ -79,11 +80,11 @@ struct Int
)
%}
if ::LibGMP::UI::MIN <= {{ var }} <= ::LibGMP::UI::MAX
{{ exps[0] }}
{{ exps[:ui] }}
elsif {{ var }}.responds_to?(:abs_unsigned) && {{ var }}.abs_unsigned <= ::LibGMP::UI::MAX
{{ exps[1] }}
{{ exps[:neg_ui] }}
else
{{ exps[2] }}
{{ exps[:big_i] }}
end
end
end
Expand Down

0 comments on commit d4cea5f

Please sign in to comment.