Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Raise on Big*#to_u with negative values #8826

Merged
merged 3 commits into from
Feb 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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