Skip to content

Commit 6125042

Browse files
committed
py: int: Fix __neg__(IntMin) and __round__(IntMin)
1 parent 0e6bb4c commit 6125042

File tree

3 files changed

+27
-12
lines changed

3 files changed

+27
-12
lines changed

py/bigint.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ func convertToBigInt(other Object) (*BigInt, bool) {
5757
//
5858
// If it is outside the range of an Int it will return an error
5959
func (x *BigInt) Int() (Int, error) {
60-
if (*big.Int)(x).BitLen() <= 63 || ((*big.Int)(x).Cmp((*big.Int)(bigIntMax)) <= 0 && (*big.Int)(x).Cmp((*big.Int)(bigIntMin)) >= 0) {
60+
if (*big.Int)(x).Cmp((*big.Int)(bigIntMax)) <= 0 && (*big.Int)(x).Cmp((*big.Int)(bigIntMin)) >= 0 {
6161
return Int((*big.Int)(x).Int64()), nil
6262
}
6363
return 0, overflowError

py/int.go

+8-5
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ type Int int64
2929

3030
const (
3131
// Maximum possible Int
32-
IntMax = 1<<63 - 1
32+
IntMax = math.MaxInt64
3333
// Minimum possible Int
34-
IntMin = -IntMax - 1
34+
IntMin = math.MinInt64
3535
// The largest number such that sqrtIntMax**2 < IntMax
3636
sqrtIntMax = 3037000499
3737
)
@@ -208,7 +208,10 @@ func convertToInt(other Object) (Int, bool) {
208208

209209
func (a Int) M__neg__() (Object, error) {
210210
if a == IntMin {
211-
// FIXME upconvert
211+
// Upconvert overflowing case
212+
r := big.NewInt(IntMin)
213+
r.Neg(r)
214+
return (*BigInt)(r), nil
212215
}
213216
return -a, nil
214217
}
@@ -600,8 +603,8 @@ func (a Int) M__round__(digits Object) (Object, error) {
600603
if b >= 0 {
601604
return a, nil
602605
}
603-
// Promote to BigInt if 10**-b > 2**63
604-
if b <= -19 {
606+
// Promote to BigInt if 10**-b > 2**63 or a == IntMin
607+
if b <= -19 || a == IntMin {
605608
return (*BigInt)(big.NewInt(int64(a))).M__round__(digits)
606609
}
607610
negative := false

py/tests/int.py

+18-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
tenE5 = 10**5
22
tenE30 = 10**30
3+
minInt = -9223372036854775807 - 1
4+
negativeMinInt = 9223372036854775808
5+
minIntMinus1 = -9223372036854775809
6+
maxInt = 9223372036854775807
7+
maxIntPlus1 = 9223372036854775808
38
def assertRaises(expecting, s, base=None):
49
try:
510
if base is None:
@@ -11,6 +16,10 @@ def assertRaises(expecting, s, base=None):
1116
else:
1217
assert False, "%s not raised" % (expecting,)
1318

19+
doc="test overflow"
20+
assert int("1000000000000000000") == 10**18
21+
assert int("-1000000000000000000") == -(10**18)
22+
1423
doc="test int, base given"
1524
assert(int("0")) == 0
1625
assert int("100000") == tenE5
@@ -136,6 +145,7 @@ def assertRaises(expecting, s, base=None):
136145
assert (--292603994644321966505444317896) == 292603994644321966505444317896
137146
assert (-4904044993697762927) == -4904044993697762927
138147
assert (--632185230151707693891374184935) == 632185230151707693891374184935
148+
assert -minInt == negativeMinInt
139149

140150
doc='unop +'
141151
assert (+4719256603434449864) == 4719256603434449864
@@ -176,12 +186,14 @@ def assertRaises(expecting, s, base=None):
176186
assert (-176718547129178599967375295570+7678395671186597946) == -176718547121500204296188697624
177187
assert (-5879237725499463452+889376233866105569867940154332) == 889376233860226332142440690880
178188
assert (98658199509207548571836763459+387058448750433331636504801219) == 485716648259640880208341564678
189+
assert maxInt + 1 == maxIntPlus1
179190

180191
doc='binop -'
181192
assert (4772705708577961331-5705965083165035349) == -933259374587074018
182193
assert (499315272741938423066045562929-926208313550490229) == 499315272741012214752495072700
183194
assert (633856083481094280-159764016488340676251173465833) == -159764016487706820167692371553
184195
assert (-759163582033099930583898215388--622263396021282398807422972137) == -136900186011817531776475243251
196+
assert minInt - 1 == minIntMinus1
185197

186198
doc='binop *'
187199
assert (7585194605759361091*-8295333006057173661) == -62921715170522459096653183904593424151
@@ -572,19 +584,19 @@ def approxEqual(a, b):
572584
assert round(12345678, -4) == 12350000
573585
assert round(12345678, -6) == 12000000
574586
assert round(12345678, -8) == 0
575-
assert round(9223372036854775807, -17) == 9200000000000000000
576-
assert round(9223372036854775807, -18) == 9000000000000000000
577-
assert round(9223372036854775807, -19) == 10000000000000000000
587+
assert round(maxInt, -17) == 9200000000000000000
588+
assert round(maxInt, -18) == 9000000000000000000
589+
assert round(maxInt, -19) == 10000000000000000000
578590

579591
assert round(-12345678, 10) == -12345678
580592
assert round(-12345678, 0) == -12345678
581593
assert round(-12345678, -2) == -12345700
582594
assert round(-12345678, -4) == -12350000
583595
assert round(-12345678, -6) == -12000000
584596
assert round(-12345678, -8) == 0
585-
assert round(-9223372036854775808, -17) == -9200000000000000000
586-
assert round(-9223372036854775808, -18) == -9000000000000000000
587-
assert round(-9223372036854775808, -19) == -10000000000000000000
597+
assert round(minInt, -17) == -9200000000000000000
598+
assert round(minInt, -18) == -9000000000000000000
599+
assert round(minInt, -19) == -10000000000000000000
588600

589601
assert round(123456789012345678901, 10) == 123456789012345678901
590602
assert round(123456789012345678901, 0) == 123456789012345678901

0 commit comments

Comments
 (0)