Skip to content

Commit

Permalink
Merge pull request #8826 from Sija/fix-8798
Browse files Browse the repository at this point in the history
Raise on `Big*#to_u` with negative values
  • Loading branch information
asterite authored Feb 21, 2020
2 parents b72404a + c429e57 commit 815c39a
Show file tree
Hide file tree
Showing 6 changed files with 26 additions and 19 deletions.
8 changes: 4 additions & 4 deletions spec/std/big/big_decimal_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -348,11 +348,11 @@ describe BigDecimal do
bd6.to_i.should eq -1

bd1.to_u.should eq 0
bd2.to_u.should eq 0
expect_raises(OverflowError) { bd2.to_u }
bd3.to_u.should eq 123
bd4.to_u.should eq 123
bd5.to_u.should eq 123
bd6.to_u.should eq 1
expect_raises(OverflowError) { bd4.to_u }
expect_raises(OverflowError) { bd5.to_u }
expect_raises(OverflowError) { bd6.to_u }

bd1.to_f.should eq 0.00123
bd2.to_f.should eq -0.00123
Expand Down
3 changes: 3 additions & 0 deletions spec/std/big/big_float_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,9 @@ describe "BigFloat" do
it { 1.34.to_big_f.to_u.should eq(1) }
it { 123.to_big_f.to_u.should eq(123) }
it { 4321.to_big_f.to_u.should eq(4321) }
it do
expect_raises(OverflowError) { -123.34.to_big_f.to_u }
end
end

describe "to_u!" do
Expand Down
2 changes: 2 additions & 0 deletions spec/std/big/big_int_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,8 @@ describe "BigInt" do
big.to_u16!.should eq(722)
big.to_u32.should eq(1234567890)

expect_raises(OverflowError) { BigInt.new(-1234567890).to_u }

u64 = big.to_u64
u64.should eq(1234567890)
u64.should be_a(UInt64)
Expand Down
28 changes: 14 additions & 14 deletions src/big/big_decimal.cr
Original file line number Diff line number Diff line change
Expand Up @@ -410,39 +410,39 @@ struct BigDecimal < Number
end

private def to_big_u
raise OverflowError.new if self < 0
to_big_u!
end

private def to_big_u!
(@value.abs // TEN ** @scale)
end

# Converts to `UInt64`. Truncates anything on the right side of the decimal point,
# converting negative to positive.
# Converts to `UInt64`. Truncates anything on the right side of the decimal point.
# Raises `OverflowError` in case of overflow.
def to_u64
to_big_u.to_u64
end

# Converts to `UInt32`. Truncates anything on the right side of the decimal point,
# converting negative to positive.
# Converts to `UInt32`. Truncates anything on the right side of the decimal point.
# Raises `OverflowError` in case of overflow.
def to_u32
to_big_u.to_u32
end

# Converts to `UInt16`. Truncates anything on the right side of the decimal point,
# converting negative to positive.
# Converts to `UInt16`. Truncates anything on the right side of the decimal point.
# Raises `OverflowError` in case of overflow.
def to_u16
to_big_u.to_u16
end

# Converts to `UInt8`. Truncates anything on the right side of the decimal point,
# converting negative to positive.
# Converts to `UInt8`. Truncates anything on the right side of the decimal point.
# Raises `OverflowError` in case of overflow.
def to_u8
to_big_u.to_u8
end

# Converts to `UInt32`. Truncates anything on the right side of the decimal point,
# converting negative to positive.
# Converts to `UInt32`. Truncates anything on the right side of the decimal point.
# Raises `OverflowError` in case of overflow.
def to_u
to_u32
Expand All @@ -452,28 +452,28 @@ struct BigDecimal < Number
# converting negative to positive.
# In case of overflow a wrapping is performed.
def to_u8!
to_big_u.to_u8!
to_big_u!.to_u8!
end

# Converts to `UInt16`. Truncates anything on the right side of the decimal point,
# converting negative to positive.
# In case of overflow a wrapping is performed.
def to_u16!
to_big_u.to_u16!
to_big_u!.to_u16!
end

# Converts to `UInt32`. Truncates anything on the right side of the decimal point,
# converting negative to positive.
# In case of overflow a wrapping is performed.
def to_u32!
to_big_u.to_u32!
to_big_u!.to_u32!
end

# Converts to `UInt64`. Truncates anything on the right side of the decimal point,
# converting negative to positive.
# In case of overflow a wrapping is performed.
def to_u64!
to_big_u.to_u64!
to_big_u!.to_u64!
end

# Converts to `UInt32`. Truncates anything on the right side of the decimal point,
Expand Down
1 change: 1 addition & 0 deletions src/big/big_float.cr
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ struct BigFloat < Float
end

def to_u64
raise OverflowError.new if self < 0
LibGMP.mpf_get_ui(self)
end

Expand Down
3 changes: 2 additions & 1 deletion src/big/big_int.cr
Original file line number Diff line number Diff line change
Expand Up @@ -500,10 +500,11 @@ struct BigInt < Int
end

def to_u32
LibGMP.get_ui(self).to_u32
to_u64.to_u32
end

def to_u64
raise OverflowError.new if self < 0
if LibGMP::ULong == UInt64 || (UInt32::MIN <= self <= UInt32::MAX)
LibGMP.get_ui(self).to_u64
else
Expand Down

0 comments on commit 815c39a

Please sign in to comment.