Skip to content

Commit

Permalink
py: int: Fix __neg__(IntMin) and __round__(IntMin)
Browse files Browse the repository at this point in the history
  • Loading branch information
ncw committed Jun 3, 2015
1 parent 0e6bb4c commit 6125042
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 12 deletions.
2 changes: 1 addition & 1 deletion py/bigint.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func convertToBigInt(other Object) (*BigInt, bool) {
//
// If it is outside the range of an Int it will return an error
func (x *BigInt) Int() (Int, error) {
if (*big.Int)(x).BitLen() <= 63 || ((*big.Int)(x).Cmp((*big.Int)(bigIntMax)) <= 0 && (*big.Int)(x).Cmp((*big.Int)(bigIntMin)) >= 0) {
if (*big.Int)(x).Cmp((*big.Int)(bigIntMax)) <= 0 && (*big.Int)(x).Cmp((*big.Int)(bigIntMin)) >= 0 {
return Int((*big.Int)(x).Int64()), nil
}
return 0, overflowError
Expand Down
13 changes: 8 additions & 5 deletions py/int.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ type Int int64

const (
// Maximum possible Int
IntMax = 1<<63 - 1
IntMax = math.MaxInt64
// Minimum possible Int
IntMin = -IntMax - 1
IntMin = math.MinInt64
// The largest number such that sqrtIntMax**2 < IntMax
sqrtIntMax = 3037000499
)
Expand Down Expand Up @@ -208,7 +208,10 @@ func convertToInt(other Object) (Int, bool) {

func (a Int) M__neg__() (Object, error) {
if a == IntMin {
// FIXME upconvert
// Upconvert overflowing case
r := big.NewInt(IntMin)
r.Neg(r)
return (*BigInt)(r), nil
}
return -a, nil
}
Expand Down Expand Up @@ -600,8 +603,8 @@ func (a Int) M__round__(digits Object) (Object, error) {
if b >= 0 {
return a, nil
}
// Promote to BigInt if 10**-b > 2**63
if b <= -19 {
// Promote to BigInt if 10**-b > 2**63 or a == IntMin
if b <= -19 || a == IntMin {
return (*BigInt)(big.NewInt(int64(a))).M__round__(digits)
}
negative := false
Expand Down
24 changes: 18 additions & 6 deletions py/tests/int.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
tenE5 = 10**5
tenE30 = 10**30
minInt = -9223372036854775807 - 1
negativeMinInt = 9223372036854775808
minIntMinus1 = -9223372036854775809
maxInt = 9223372036854775807
maxIntPlus1 = 9223372036854775808
def assertRaises(expecting, s, base=None):
try:
if base is None:
Expand All @@ -11,6 +16,10 @@ def assertRaises(expecting, s, base=None):
else:
assert False, "%s not raised" % (expecting,)

doc="test overflow"
assert int("1000000000000000000") == 10**18
assert int("-1000000000000000000") == -(10**18)

doc="test int, base given"
assert(int("0")) == 0
assert int("100000") == tenE5
Expand Down Expand Up @@ -136,6 +145,7 @@ def assertRaises(expecting, s, base=None):
assert (--292603994644321966505444317896) == 292603994644321966505444317896
assert (-4904044993697762927) == -4904044993697762927
assert (--632185230151707693891374184935) == 632185230151707693891374184935
assert -minInt == negativeMinInt

doc='unop +'
assert (+4719256603434449864) == 4719256603434449864
Expand Down Expand Up @@ -176,12 +186,14 @@ def assertRaises(expecting, s, base=None):
assert (-176718547129178599967375295570+7678395671186597946) == -176718547121500204296188697624
assert (-5879237725499463452+889376233866105569867940154332) == 889376233860226332142440690880
assert (98658199509207548571836763459+387058448750433331636504801219) == 485716648259640880208341564678
assert maxInt + 1 == maxIntPlus1

doc='binop -'
assert (4772705708577961331-5705965083165035349) == -933259374587074018
assert (499315272741938423066045562929-926208313550490229) == 499315272741012214752495072700
assert (633856083481094280-159764016488340676251173465833) == -159764016487706820167692371553
assert (-759163582033099930583898215388--622263396021282398807422972137) == -136900186011817531776475243251
assert minInt - 1 == minIntMinus1

doc='binop *'
assert (7585194605759361091*-8295333006057173661) == -62921715170522459096653183904593424151
Expand Down Expand Up @@ -572,19 +584,19 @@ def approxEqual(a, b):
assert round(12345678, -4) == 12350000
assert round(12345678, -6) == 12000000
assert round(12345678, -8) == 0
assert round(9223372036854775807, -17) == 9200000000000000000
assert round(9223372036854775807, -18) == 9000000000000000000
assert round(9223372036854775807, -19) == 10000000000000000000
assert round(maxInt, -17) == 9200000000000000000
assert round(maxInt, -18) == 9000000000000000000
assert round(maxInt, -19) == 10000000000000000000

assert round(-12345678, 10) == -12345678
assert round(-12345678, 0) == -12345678
assert round(-12345678, -2) == -12345700
assert round(-12345678, -4) == -12350000
assert round(-12345678, -6) == -12000000
assert round(-12345678, -8) == 0
assert round(-9223372036854775808, -17) == -9200000000000000000
assert round(-9223372036854775808, -18) == -9000000000000000000
assert round(-9223372036854775808, -19) == -10000000000000000000
assert round(minInt, -17) == -9200000000000000000
assert round(minInt, -18) == -9000000000000000000
assert round(minInt, -19) == -10000000000000000000

assert round(123456789012345678901, 10) == 123456789012345678901
assert round(123456789012345678901, 0) == 123456789012345678901
Expand Down

0 comments on commit 6125042

Please sign in to comment.