diff --git a/spec/std/int_spec.cr b/spec/std/int_spec.cr index 6d61074b2420..948a4e69e88f 100644 --- a/spec/std/int_spec.cr +++ b/spec/std/int_spec.cr @@ -195,6 +195,53 @@ describe "Int" do {% end %} end + describe "#to_unsigned" do + {% for n in [8, 16, 32, 64, 128] %} + it "does for Int{{n}}" do + x = 123_i{{n}}.to_unsigned + x.should be_a(UInt{{n}}) + x.should eq(123) + + Int{{n}}.zero.to_unsigned.should eq(UInt{{n}}::MIN) + Int{{n}}::MAX.to_unsigned.should eq(UInt{{n}}.new(Int{{n}}::MAX)) + expect_raises(OverflowError) { Int{{n}}::MIN.to_unsigned } + end + + it "does for UInt{{n}}" do + x = 123_u{{n}}.to_unsigned + x.should be_a(UInt{{n}}) + x.should eq(123) + + UInt{{n}}::MIN.to_unsigned.should eq(UInt{{n}}::MIN) + UInt{{n}}::MAX.to_unsigned.should eq(UInt{{n}}::MAX) + end + {% end %} + end + + describe "#to_unsigned!" do + {% for n in [8, 16, 32, 64, 128] %} + it "does for Int{{n}}" do + x = Int{{n}}.new(123).to_unsigned! + x.should be_a(UInt{{n}}) + x.should eq(123) + + (-123_i{{n}}).to_unsigned!.should eq(UInt{{n}}::MAX - 122) + Int{{n}}::MIN.to_unsigned!.should eq(UInt{{n}}::MAX // 2 + 1) + Int{{n}}::MAX.to_unsigned!.should eq(UInt{{n}}::MAX // 2) + (-1_i{{n}}).to_unsigned!.should eq(UInt{{n}}::MAX) + end + + it "does for UInt{{n}}" do + x = 123_u{{n}}.to_unsigned! + x.should be_a(UInt{{n}}) + x.should eq(123) + + UInt{{n}}::MIN.to_unsigned!.should eq(UInt{{n}}::MIN) + UInt{{n}}::MAX.to_unsigned!.should eq(UInt{{n}}::MAX) + end + {% end %} + end + describe "#abs_unsigned" do {% for int in Int::Signed.union_types %} it "does for {{ int }}" do diff --git a/src/int.cr b/src/int.cr index a4aa94377fff..6f0d3aa5881a 100644 --- a/src/int.cr +++ b/src/int.cr @@ -925,6 +925,34 @@ struct Int8 self end + # Returns `self` converted to an unsigned value of the same size. + # + # Simply returns `self` unmodified if `self` is already an `Int::Unsigned`. + # Raises `OverflowError` in case of overflow. + # + # ``` + # 1_i32.to_unsigned # => 1_u32 + # 2_i16.to_unsigned # => 2_u16 + # 3_u64.to_unsigned # => 3_u64 + # ``` + def to_unsigned : UInt8 + to_u8 + end + + # Returns `self` converted to an unsigned value of the same size, wrapping in + # case of overflow. + # + # Simply returns `self` unmodified if `self` is already an `Int::Unsigned`. + # + # ``` + # 1_i32.to_unsigned! # => 1_u32 + # (-6_i16).to_unsigned! # => 65530_u16 + # 3_u64.to_unsigned! # => 3_u64 + # ``` + def to_unsigned! : UInt8 + to_u8! + end + # Returns the absolute value of `self` as an unsigned value of the same size. # # Returns `self` if `self` is already an `Int::Unsigned`. This method never @@ -1083,6 +1111,34 @@ struct Int16 self end + # Returns `self` converted to an unsigned value of the same size. + # + # Simply returns `self` unmodified if `self` is already an `Int::Unsigned`. + # Raises `OverflowError` in case of overflow. + # + # ``` + # 1_i32.to_unsigned # => 1_u32 + # 2_i16.to_unsigned # => 2_u16 + # 3_u64.to_unsigned # => 3_u64 + # ``` + def to_unsigned : UInt16 + to_u16 + end + + # Returns `self` converted to an unsigned value of the same size, wrapping in + # case of overflow. + # + # Simply returns `self` unmodified if `self` is already an `Int::Unsigned`. + # + # ``` + # 1_i32.to_unsigned! # => 1_u32 + # (-6_i16).to_unsigned! # => 65530_u16 + # 3_u64.to_unsigned! # => 3_u64 + # ``` + def to_unsigned! : UInt16 + to_u16! + end + # Returns the absolute value of `self` as an unsigned value of the same size. # # Returns `self` if `self` is already an `Int::Unsigned`. This method never @@ -1241,6 +1297,34 @@ struct Int32 self end + # Returns `self` converted to an unsigned value of the same size. + # + # Simply returns `self` unmodified if `self` is already an `Int::Unsigned`. + # Raises `OverflowError` in case of overflow. + # + # ``` + # 1_i32.to_unsigned # => 1_u32 + # 2_i16.to_unsigned # => 2_u16 + # 3_u64.to_unsigned # => 3_u64 + # ``` + def to_unsigned : UInt32 + to_u32 + end + + # Returns `self` converted to an unsigned value of the same size, wrapping in + # case of overflow. + # + # Simply returns `self` unmodified if `self` is already an `Int::Unsigned`. + # + # ``` + # 1_i32.to_unsigned! # => 1_u32 + # (-6_i16).to_unsigned! # => 65530_u16 + # 3_u64.to_unsigned! # => 3_u64 + # ``` + def to_unsigned! : UInt32 + to_u32! + end + # Returns the absolute value of `self` as an unsigned value of the same size. # # Returns `self` if `self` is already an `Int::Unsigned`. This method never @@ -1399,6 +1483,34 @@ struct Int64 self end + # Returns `self` converted to an unsigned value of the same size. + # + # Simply returns `self` unmodified if `self` is already an `Int::Unsigned`. + # Raises `OverflowError` in case of overflow. + # + # ``` + # 1_i32.to_unsigned # => 1_u32 + # 2_i16.to_unsigned # => 2_u16 + # 3_u64.to_unsigned # => 3_u64 + # ``` + def to_unsigned : UInt64 + to_u64 + end + + # Returns `self` converted to an unsigned value of the same size, wrapping in + # case of overflow. + # + # Simply returns `self` unmodified if `self` is already an `Int::Unsigned`. + # + # ``` + # 1_i32.to_unsigned! # => 1_u32 + # (-6_i16).to_unsigned! # => 65530_u16 + # 3_u64.to_unsigned! # => 3_u64 + # ``` + def to_unsigned! : UInt64 + to_u64! + end + # Returns the absolute value of `self` as an unsigned value of the same size. # # Returns `self` if `self` is already an `Int::Unsigned`. This method never @@ -1560,6 +1672,34 @@ struct Int128 self end + # Returns `self` converted to an unsigned value of the same size. + # + # Simply returns `self` unmodified if `self` is already an `Int::Unsigned`. + # Raises `OverflowError` in case of overflow. + # + # ``` + # 1_i32.to_unsigned # => 1_u32 + # 2_i16.to_unsigned # => 2_u16 + # 3_u64.to_unsigned # => 3_u64 + # ``` + def to_unsigned : UInt128 + to_u128 + end + + # Returns `self` converted to an unsigned value of the same size, wrapping in + # case of overflow. + # + # Simply returns `self` unmodified if `self` is already an `Int::Unsigned`. + # + # ``` + # 1_i32.to_unsigned! # => 1_u32 + # (-6_i16).to_unsigned! # => 65530_u16 + # 3_u64.to_unsigned! # => 3_u64 + # ``` + def to_unsigned! : UInt128 + to_u128! + end + # Returns the absolute value of `self` as an unsigned value of the same size. # # Returns `self` if `self` is already an `Int::Unsigned`. This method never @@ -1718,6 +1858,34 @@ struct UInt8 to_i8! end + # Returns `self` converted to an unsigned value of the same size. + # + # Simply returns `self` unmodified if `self` is already an `Int::Unsigned`. + # Raises `OverflowError` in case of overflow. + # + # ``` + # 1_i32.to_unsigned # => 1_u32 + # 2_i16.to_unsigned # => 2_u16 + # 3_u64.to_unsigned # => 3_u64 + # ``` + def to_unsigned : UInt8 + self + end + + # Returns `self` converted to an unsigned value of the same size, wrapping in + # case of overflow. + # + # Simply returns `self` unmodified if `self` is already an `Int::Unsigned`. + # + # ``` + # 1_i32.to_unsigned! # => 1_u32 + # (-6_i16).to_unsigned! # => 65530_u16 + # 3_u64.to_unsigned! # => 3_u64 + # ``` + def to_unsigned! : UInt8 + self + end + def abs : self self end @@ -1880,6 +2048,34 @@ struct UInt16 to_i16! end + # Returns `self` converted to an unsigned value of the same size. + # + # Simply returns `self` unmodified if `self` is already an `Int::Unsigned`. + # Raises `OverflowError` in case of overflow. + # + # ``` + # 1_i32.to_unsigned # => 1_u32 + # 2_i16.to_unsigned # => 2_u16 + # 3_u64.to_unsigned # => 3_u64 + # ``` + def to_unsigned : UInt16 + self + end + + # Returns `self` converted to an unsigned value of the same size, wrapping in + # case of overflow. + # + # Simply returns `self` unmodified if `self` is already an `Int::Unsigned`. + # + # ``` + # 1_i32.to_unsigned! # => 1_u32 + # (-6_i16).to_unsigned! # => 65530_u16 + # 3_u64.to_unsigned! # => 3_u64 + # ``` + def to_unsigned! : UInt16 + self + end + def abs : self self end @@ -2042,6 +2238,34 @@ struct UInt32 to_i32! end + # Returns `self` converted to an unsigned value of the same size. + # + # Simply returns `self` unmodified if `self` is already an `Int::Unsigned`. + # Raises `OverflowError` in case of overflow. + # + # ``` + # 1_i32.to_unsigned # => 1_u32 + # 2_i16.to_unsigned # => 2_u16 + # 3_u64.to_unsigned # => 3_u64 + # ``` + def to_unsigned : UInt32 + self + end + + # Returns `self` converted to an unsigned value of the same size, wrapping in + # case of overflow. + # + # Simply returns `self` unmodified if `self` is already an `Int::Unsigned`. + # + # ``` + # 1_i32.to_unsigned! # => 1_u32 + # (-6_i16).to_unsigned! # => 65530_u16 + # 3_u64.to_unsigned! # => 3_u64 + # ``` + def to_unsigned! : UInt32 + self + end + def abs : self self end @@ -2204,6 +2428,34 @@ struct UInt64 to_i64! end + # Returns `self` converted to an unsigned value of the same size. + # + # Simply returns `self` unmodified if `self` is already an `Int::Unsigned`. + # Raises `OverflowError` in case of overflow. + # + # ``` + # 1_i32.to_unsigned # => 1_u32 + # 2_i16.to_unsigned # => 2_u16 + # 3_u64.to_unsigned # => 3_u64 + # ``` + def to_unsigned : UInt64 + self + end + + # Returns `self` converted to an unsigned value of the same size, wrapping in + # case of overflow. + # + # Simply returns `self` unmodified if `self` is already an `Int::Unsigned`. + # + # ``` + # 1_i32.to_unsigned! # => 1_u32 + # (-6_i16).to_unsigned! # => 65530_u16 + # 3_u64.to_unsigned! # => 3_u64 + # ``` + def to_unsigned! : UInt64 + self + end + def abs : self self end @@ -2368,6 +2620,34 @@ struct UInt128 to_i128! end + # Returns `self` converted to an unsigned value of the same size. + # + # Simply returns `self` unmodified if `self` is already an `Int::Unsigned`. + # Raises `OverflowError` in case of overflow. + # + # ``` + # 1_i32.to_unsigned # => 1_u32 + # 2_i16.to_unsigned # => 2_u16 + # 3_u64.to_unsigned # => 3_u64 + # ``` + def to_unsigned : UInt128 + self + end + + # Returns `self` converted to an unsigned value of the same size, wrapping in + # case of overflow. + # + # Simply returns `self` unmodified if `self` is already an `Int::Unsigned`. + # + # ``` + # 1_i32.to_unsigned! # => 1_u32 + # (-6_i16).to_unsigned! # => 65530_u16 + # 3_u64.to_unsigned! # => 3_u64 + # ``` + def to_unsigned! : UInt128 + self + end + def abs self end