Skip to content

Commit

Permalink
Add Number#integer? (crystal-lang#13936)
Browse files Browse the repository at this point in the history
  • Loading branch information
HertzDevil authored Nov 2, 2023
1 parent 5d68979 commit 57d9397
Show file tree
Hide file tree
Showing 11 changed files with 94 additions and 1 deletion.
12 changes: 12 additions & 0 deletions spec/std/big/big_decimal_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -969,6 +969,18 @@ describe BigDecimal do
(-1.to_big_d - BigDecimal.new(50000, 204)).round(200, mode: :ties_even).should eq(-1.to_big_d - BigDecimal.new(5, 200))
end
end

describe "#integer?" do
it { BigDecimal.new(0, 0).integer?.should be_true }
it { BigDecimal.new(1, 0).integer?.should be_true }
it { BigDecimal.new(10, 0).integer?.should be_true }
it { BigDecimal.new(-10, 1).integer?.should be_true }
it { BigDecimal.new(10000, 4).integer?.should be_true }

it { BigDecimal.new(1, 1).integer?.should be_false }
it { BigDecimal.new(13, 2).integer?.should be_false }
it { BigDecimal.new(-2400, 3).integer?.should be_false }
end
end

describe "#inspect" do
Expand Down
6 changes: 6 additions & 0 deletions spec/std/big/big_float_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,12 @@ describe "BigFloat" do
end
end

describe "#integer?" do
it { BigFloat.zero.integer?.should be_true }
it { 1.to_big_f.integer?.should be_true }
it { 1.2.to_big_f.integer?.should be_false }
end

it "#hash" do
b = 123.to_big_f
b.hash.should eq(b.to_f64.hash)
Expand Down
5 changes: 5 additions & 0 deletions spec/std/big/big_int_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ private def it_converts_to_s(num, str, *, file = __FILE__, line = __LINE__, **op
end

describe "BigInt" do
describe "#integer?" do
it { BigInt.zero.integer?.should be_true }
it { 12345.to_big_i.integer?.should be_true }
end

it "creates with a value of zero" do
BigInt.new.to_s.should eq("0")
end
Expand Down
9 changes: 9 additions & 0 deletions spec/std/big/big_rational_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,15 @@ describe BigRational do
end
end

describe "#integer?" do
it { br(0, 1).integer?.should be_true }
it { br(1, 1).integer?.should be_true }
it { br(9, 3).integer?.should be_true }
it { br(-126, 7).integer?.should be_true }
it { br(5, 2).integer?.should be_false }
it { br(7, -3).integer?.should be_false }
end

it "#hash" do
b = br(10, 3)
hash = b.hash
Expand Down
17 changes: 17 additions & 0 deletions spec/std/float_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,23 @@ describe "Float" do
it { 2.9.ceil.should eq(3) }
end

describe "#integer?" do
it { 1.0_f32.integer?.should be_true }
it { 1.0_f64.integer?.should be_true }

it { 1.2_f32.integer?.should be_false }
it { 1.2_f64.integer?.should be_false }

it { Float32::MAX.integer?.should be_true }
it { Float64::MAX.integer?.should be_true }

it { Float32::INFINITY.integer?.should be_false }
it { Float64::INFINITY.integer?.should be_false }

it { Float32::NAN.integer?.should be_false }
it { Float64::NAN.integer?.should be_false }
end

describe "fdiv" do
it { 1.0.fdiv(1).should eq 1.0 }
it { 1.0.fdiv(2).should eq 0.5 }
Expand Down
7 changes: 7 additions & 0 deletions spec/std/int_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ private macro it_converts_to_s(num, str, **opts)
end

describe "Int" do
describe "#integer?" do
{% for int in BUILTIN_INTEGER_TYPES %}
it { {{ int }}::MIN.integer?.should be_true }
it { {{ int }}::MAX.integer?.should be_true }
{% end %}
end

describe "**" do
it "with positive Int32" do
x = 2 ** 2
Expand Down
6 changes: 6 additions & 0 deletions src/big/big_decimal.cr
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,12 @@ struct BigDecimal < Number
BigDecimal.new(mantissa, 0)
end

# :inherit:
def integer? : Bool
factor_powers_of_ten
scale == 0
end

def round(digits : Number, base = 10, *, mode : RoundingMode = :ties_even) : BigDecimal
return self if zero?

Expand Down
3 changes: 2 additions & 1 deletion src/big/big_float.cr
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,8 @@ struct BigFloat < Float
end
end

protected def integer?
# :inherit:
def integer? : Bool
!LibGMP.mpf_integer_p(mpf).zero?
end

Expand Down
7 changes: 7 additions & 0 deletions src/big/big_rational.cr
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,13 @@ struct BigRational < Number
x
end

# :inherit:
def integer? : Bool
# since all `BigRational`s are canonicalized, the denominator must be
# positive and coprime with the numerator
denominator == 1
end

# Divides the rational by (2 ** *other*)
#
# ```
Expand Down
7 changes: 7 additions & 0 deletions src/int.cr
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,13 @@ struct Int
self
end

# :inherit:
#
# Always returns `true` for `Int`.
def integer? : Bool
true
end

# Returns the value of raising `self` to the power of *exponent*.
#
# Raises `ArgumentError` if *exponent* is negative: if this is needed,
Expand Down
16 changes: 16 additions & 0 deletions src/number.cr
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,22 @@ struct Number
end
end

# Returns `true` if `self` is an integer.
#
# Non-integer types may return `true` as long as `self` denotes a finite value
# without any fractional parts.
#
# ```
# 1.integer? # => true
# 1.0.integer? # => true
# 1.2.integer? # => false
# (1 / 0).integer? # => false
# (0 / 0).integer? # => false
# ```
def integer? : Bool
self % 1 == 0
end

# Returns `true` if `self` is equal to zero.
#
# ```
Expand Down

0 comments on commit 57d9397

Please sign in to comment.