Skip to content

Commit

Permalink
#abs_unsigned
Browse files Browse the repository at this point in the history
  • Loading branch information
HertzDevil committed Nov 2, 2023
1 parent 6e3a66e commit f1c5745
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 10 deletions.
26 changes: 26 additions & 0 deletions spec/std/int_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,32 @@ describe "Int" do
end
end

describe "#abs_unsigned" do
{% for int in Int::Signed.union_types %}
it "does for {{ int }}" do
x = {{ int }}.new(123).abs_unsigned
x.should be_a(U{{ int }})
x.should eq(123)

x = {{ int }}.new(-123).abs_unsigned
x.should be_a(U{{ int }})
x.should eq(123)
end

it "does for U{{ int }}" do
x = U{{ int }}.new(123).abs_unsigned
x.should be_a(U{{ int }})
x.should eq(123)
end

it "does not overflow on {{ int }}::MIN" do
x = {{ int }}::MIN.abs_unsigned
x.should be_a(U{{ int }})
x.should eq(U{{ int }}.zero &- {{ int }}::MIN)
end
{% end %}
end

describe "gcd" do
it { 14.gcd(0).should eq(14) }
it { 14.gcd(1).should eq(1) }
Expand Down
120 changes: 110 additions & 10 deletions src/int.cr
Original file line number Diff line number Diff line change
Expand Up @@ -890,7 +890,17 @@ struct Int8
0_i8 - self
end

# :nodoc:
# 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
# overflows.
#
# ```
# 1_u32.abs_unsigned # => 1_u32
# 2_i32.abs_unsigned # => 2_u32
# -3_i8.abs_unsigned # => 3_u8
# Int16::MIN.abs_unsigned # => 32768_u16
# ```
def abs_unsigned : UInt8
self < 0 ? 0_u8 &- self : to_u8!
end
Expand Down Expand Up @@ -1000,7 +1010,17 @@ struct Int16
0_i16 - self
end

# :nodoc:
# 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
# overflows.
#
# ```
# 1_u32.abs_unsigned # => 1_u32
# 2_i32.abs_unsigned # => 2_u32
# -3_i8.abs_unsigned # => 3_u8
# Int16::MIN.abs_unsigned # => 32768_u16
# ```
def abs_unsigned : UInt16
self < 0 ? 0_u16 &- self : to_u16!
end
Expand Down Expand Up @@ -1110,7 +1130,17 @@ struct Int32
0 - self
end

# :nodoc:
# 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
# overflows.
#
# ```
# 1_u32.abs_unsigned # => 1_u32
# 2_i32.abs_unsigned # => 2_u32
# -3_i8.abs_unsigned # => 3_u8
# Int16::MIN.abs_unsigned # => 32768_u16
# ```
def abs_unsigned : UInt32
self < 0 ? 0_u32 &- self : to_u32!
end
Expand Down Expand Up @@ -1220,7 +1250,17 @@ struct Int64
0_i64 - self
end

# :nodoc:
# 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
# overflows.
#
# ```
# 1_u32.abs_unsigned # => 1_u32
# 2_i32.abs_unsigned # => 2_u32
# -3_i8.abs_unsigned # => 3_u8
# Int16::MIN.abs_unsigned # => 32768_u16
# ```
def abs_unsigned : UInt64
self < 0 ? 0_u64 &- self : to_u64!
end
Expand Down Expand Up @@ -1333,7 +1373,17 @@ struct Int128
Int128.new(0) - self
end

# :nodoc:
# 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
# overflows.
#
# ```
# 1_u32.abs_unsigned # => 1_u32
# 2_i32.abs_unsigned # => 2_u32
# -3_i8.abs_unsigned # => 3_u8
# Int16::MIN.abs_unsigned # => 32768_u16
# ```
def abs_unsigned : UInt128
self < 0 ? UInt128.new(0) &- self : to_u128!
end
Expand Down Expand Up @@ -1447,7 +1497,17 @@ struct UInt8
self
end

# :nodoc:
# 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
# overflows.
#
# ```
# 1_u32.abs_unsigned # => 1_u32
# 2_i32.abs_unsigned # => 2_u32
# -3_i8.abs_unsigned # => 3_u8
# Int16::MIN.abs_unsigned # => 32768_u16
# ```
def abs_unsigned : self
self
end
Expand Down Expand Up @@ -1561,7 +1621,17 @@ struct UInt16
self
end

# :nodoc:
# 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
# overflows.
#
# ```
# 1_u32.abs_unsigned # => 1_u32
# 2_i32.abs_unsigned # => 2_u32
# -3_i8.abs_unsigned # => 3_u8
# Int16::MIN.abs_unsigned # => 32768_u16
# ```
def abs_unsigned : self
self
end
Expand Down Expand Up @@ -1675,7 +1745,17 @@ struct UInt32
self
end

# :nodoc:
# 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
# overflows.
#
# ```
# 1_u32.abs_unsigned # => 1_u32
# 2_i32.abs_unsigned # => 2_u32
# -3_i8.abs_unsigned # => 3_u8
# Int16::MIN.abs_unsigned # => 32768_u16
# ```
def abs_unsigned : self
self
end
Expand Down Expand Up @@ -1789,7 +1869,17 @@ struct UInt64
self
end

# :nodoc:
# 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
# overflows.
#
# ```
# 1_u32.abs_unsigned # => 1_u32
# 2_i32.abs_unsigned # => 2_u32
# -3_i8.abs_unsigned # => 3_u8
# Int16::MIN.abs_unsigned # => 32768_u16
# ```
def abs_unsigned : self
self
end
Expand Down Expand Up @@ -1905,7 +1995,17 @@ struct UInt128
self
end

# :nodoc:
# 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
# overflows.
#
# ```
# 1_u32.abs_unsigned # => 1_u32
# 2_i32.abs_unsigned # => 2_u32
# -3_i8.abs_unsigned # => 3_u8
# Int16::MIN.abs_unsigned # => 32768_u16
# ```
def abs_unsigned : self
self
end
Expand Down

0 comments on commit f1c5745

Please sign in to comment.