From 507fa5b36048090bb621dd26ea681afaa9debef3 Mon Sep 17 00:00:00 2001 From: Quinton Miller Date: Thu, 2 Nov 2023 22:53:02 +0800 Subject: [PATCH] `#neg_signed` --- spec/std/int_spec.cr | 28 ++++++++++ src/int.cr | 120 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 138 insertions(+), 10 deletions(-) diff --git a/spec/std/int_spec.cr b/spec/std/int_spec.cr index f87662602e62..fbbf77d30ef3 100644 --- a/spec/std/int_spec.cr +++ b/spec/std/int_spec.cr @@ -165,6 +165,34 @@ describe "Int" do {% end %} end + describe "#neg_signed" do + {% for int in Int::Signed.union_types %} + it "does for {{ int }}" do + x = {{ int }}.new(123).neg_signed + x.should be_a({{ int }}) + x.should eq(-123) + + x = {{ int }}.new(-123).neg_signed + x.should be_a({{ int }}) + x.should eq(123) + + expect_raises(OverflowError) { {{ int }}::MIN.neg_signed } + end + + it "does for U{{ int }}" do + x = U{{ int }}.new(123).neg_signed + x.should be_a({{ int }}) + x.should eq(-123) + end + + it "does not overflow on {{ int }}::MIN.abs_unsigned" do + x = {{ int }}::MIN.abs_unsigned.neg_signed + x.should be_a({{ int }}) + x.should eq({{ int }}::MIN) + end + {% end %} + end + describe "gcd" do it { 14.gcd(0).should eq(14) } it { 14.gcd(1).should eq(1) } diff --git a/src/int.cr b/src/int.cr index 6d7300ed53ce..fa06c5b48846 100644 --- a/src/int.cr +++ b/src/int.cr @@ -905,7 +905,17 @@ struct Int8 self < 0 ? 0_u8 &- self : to_u8! end - # :nodoc: + # Returns the negative of `self` as a signed value of the same size. + # + # Returns `-self` if `self` is already an `Int::Signed`. Raises + # `OverflowError` in case of overflow. + # + # ``` + # 1_i32.neg_signed # => -1_i32 + # 2_u16.neg_signed # => -2_i16 + # 128_u8.neg_signed # => -128_i8 + # Int16::MIN.neg_signed # raises OverflowError + # ``` def neg_signed : self -self end @@ -1025,7 +1035,17 @@ struct Int16 self < 0 ? 0_u16 &- self : to_u16! end - # :nodoc: + # Returns the negative of `self` as a signed value of the same size. + # + # Returns `-self` if `self` is already an `Int::Signed`. Raises + # `OverflowError` in case of overflow. + # + # ``` + # 1_i32.neg_signed # => -1_i32 + # 2_u16.neg_signed # => -2_i16 + # 128_u8.neg_signed # => -128_i8 + # Int16::MIN.neg_signed # raises OverflowError + # ``` def neg_signed : self -self end @@ -1145,7 +1165,17 @@ struct Int32 self < 0 ? 0_u32 &- self : to_u32! end - # :nodoc: + # Returns the negative of `self` as a signed value of the same size. + # + # Returns `-self` if `self` is already an `Int::Signed`. Raises + # `OverflowError` in case of overflow. + # + # ``` + # 1_i32.neg_signed # => -1_i32 + # 2_u16.neg_signed # => -2_i16 + # 128_u8.neg_signed # => -128_i8 + # Int16::MIN.neg_signed # raises OverflowError + # ``` def neg_signed : self -self end @@ -1265,7 +1295,17 @@ struct Int64 self < 0 ? 0_u64 &- self : to_u64! end - # :nodoc: + # Returns the negative of `self` as a signed value of the same size. + # + # Returns `-self` if `self` is already an `Int::Signed`. Raises + # `OverflowError` in case of overflow. + # + # ``` + # 1_i32.neg_signed # => -1_i32 + # 2_u16.neg_signed # => -2_i16 + # 128_u8.neg_signed # => -128_i8 + # Int16::MIN.neg_signed # raises OverflowError + # ``` def neg_signed : self -self end @@ -1388,7 +1428,17 @@ struct Int128 self < 0 ? UInt128.new(0) &- self : to_u128! end - # :nodoc: + # Returns the negative of `self` as a signed value of the same size. + # + # Returns `-self` if `self` is already an `Int::Signed`. Raises + # `OverflowError` in case of overflow. + # + # ``` + # 1_i32.neg_signed # => -1_i32 + # 2_u16.neg_signed # => -2_i16 + # 128_u8.neg_signed # => -128_i8 + # Int16::MIN.neg_signed # raises OverflowError + # ``` def neg_signed : self -self end @@ -1512,7 +1562,17 @@ struct UInt8 self end - # :nodoc: + # Returns the negative of `self` as a signed value of the same size. + # + # Returns `-self` if `self` is already an `Int::Signed`. Raises + # `OverflowError` in case of overflow. + # + # ``` + # 1_i32.neg_signed # => -1_i32 + # 2_u16.neg_signed # => -2_i16 + # 128_u8.neg_signed # => -128_i8 + # Int16::MIN.neg_signed # raises OverflowError + # ``` def neg_signed : Int8 0_i8 - self end @@ -1636,7 +1696,17 @@ struct UInt16 self end - # :nodoc: + # Returns the negative of `self` as a signed value of the same size. + # + # Returns `-self` if `self` is already an `Int::Signed`. Raises + # `OverflowError` in case of overflow. + # + # ``` + # 1_i32.neg_signed # => -1_i32 + # 2_u16.neg_signed # => -2_i16 + # 128_u8.neg_signed # => -128_i8 + # Int16::MIN.neg_signed # raises OverflowError + # ``` def neg_signed : Int16 0_i16 - self end @@ -1760,7 +1830,17 @@ struct UInt32 self end - # :nodoc: + # Returns the negative of `self` as a signed value of the same size. + # + # Returns `-self` if `self` is already an `Int::Signed`. Raises + # `OverflowError` in case of overflow. + # + # ``` + # 1_i32.neg_signed # => -1_i32 + # 2_u16.neg_signed # => -2_i16 + # 128_u8.neg_signed # => -128_i8 + # Int16::MIN.neg_signed # raises OverflowError + # ``` def neg_signed : Int32 0_i32 - self end @@ -1884,7 +1964,17 @@ struct UInt64 self end - # :nodoc: + # Returns the negative of `self` as a signed value of the same size. + # + # Returns `-self` if `self` is already an `Int::Signed`. Raises + # `OverflowError` in case of overflow. + # + # ``` + # 1_i32.neg_signed # => -1_i32 + # 2_u16.neg_signed # => -2_i16 + # 128_u8.neg_signed # => -128_i8 + # Int16::MIN.neg_signed # raises OverflowError + # ``` def neg_signed : Int64 0_i64 - self end @@ -2010,7 +2100,17 @@ struct UInt128 self end - # :nodoc: + # Returns the negative of `self` as a signed value of the same size. + # + # Returns `-self` if `self` is already an `Int::Signed`. Raises + # `OverflowError` in case of overflow. + # + # ``` + # 1_i32.neg_signed # => -1_i32 + # 2_u16.neg_signed # => -2_i16 + # 128_u8.neg_signed # => -128_i8 + # Int16::MIN.neg_signed # raises OverflowError + # ``` def neg_signed : Int128 Int128.new(0) - self end