github.com/pygolin/runtime@v0.0.0-20201208210830-a62e3cd39798/long.go (about) 1 // Copyright 2016 Google Inc. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package runtime 16 17 import ( 18 "fmt" 19 "math" 20 "math/big" 21 "reflect" 22 "strings" 23 "sync" 24 ) 25 26 // By convention in this file, we always use the variable 27 // name "z" or "m" (in the case of DivMod) to refer to 28 // a *big.Int that we intend to modify. For other big.Int 29 // values, we use "x", "y" or other names. Variables z and m 30 // must be allocated within the same function using a big.Int 31 // constructor. 32 // We must never modify the value field of a Long that has 33 // already been made available to the rest of the program, 34 // as this would violate the immutability of Python longs. 35 36 // Long represents Python 'long' objects. 37 type Long struct { 38 Object 39 value big.Int 40 hashOnce sync.Once 41 hash int 42 } 43 44 // NewLong returns a new Long holding the given value. 45 func NewLong(x *big.Int) *Long { 46 result := Long{Object: Object{typ: LongType}} 47 result.value.Set(x) 48 return &result 49 } 50 51 // NewLongFromBytes returns a new Long holding the given bytes, 52 // interpreted as a big endian unsigned integer. 53 func NewLongFromBytes(b []byte) *Long { 54 result := Long{Object: Object{typ: LongType}} 55 result.value.SetBytes(b) 56 return &result 57 } 58 59 func toLongUnsafe(o *Object) *Long { 60 return (*Long)(o.toPointer()) 61 } 62 63 // IntValue returns l's value as a plain int if it will not overflow. 64 // Otherwise raises OverflowErrorType. 65 func (l *Long) IntValue(f *Frame) (int, *BaseException) { 66 if !numInIntRange(&l.value) { 67 return 0, f.RaiseType(OverflowErrorType, "Python int too large to convert to a Go int") 68 } 69 return int(l.value.Int64()), nil 70 } 71 72 // ToObject upcasts l to an Object. 73 func (l *Long) ToObject() *Object { 74 return &l.Object 75 } 76 77 // Value returns the underlying integer value held by l. 78 func (l *Long) Value() *big.Int { 79 return new(big.Int).Set(&l.value) 80 } 81 82 // IsTrue returns false if l is zero, true otherwise. 83 func (l *Long) IsTrue() bool { 84 return l.value.Sign() != 0 85 } 86 87 // Neg returns a new Long that is the negative of l. 88 func (l *Long) Neg() *Long { 89 result := Long{Object: Object{typ: LongType}} 90 result.value.Set(&l.value) 91 result.value.Neg(&result.value) 92 return &result 93 } 94 95 // LongType is the object representing the Python 'long' type. 96 var LongType = newBasisType("long", reflect.TypeOf(Long{}), toLongUnsafe, ObjectType) 97 98 func longAbs(z, x *big.Int) { 99 z.Abs(x) 100 } 101 102 func longAdd(z, x, y *big.Int) { 103 z.Add(x, y) 104 } 105 106 func longAnd(z, x, y *big.Int) { 107 z.And(x, y) 108 } 109 110 func longDiv(z, x, y *big.Int) { 111 m := big.Int{} 112 longDivMod(x, y, z, &m) 113 } 114 115 func longDivAndMod(z, m, x, y *big.Int) { 116 longDivMod(x, y, z, m) 117 } 118 119 func longEq(x, y *big.Int) bool { 120 return x.Cmp(y) == 0 121 } 122 123 func longGE(x, y *big.Int) bool { 124 return x.Cmp(y) >= 0 125 } 126 127 func longGetNewArgs(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) { 128 if raised := checkMethodArgs(f, "__getnewargs__", args, LongType); raised != nil { 129 return nil, raised 130 } 131 return NewTuple1(args[0]).ToObject(), nil 132 } 133 134 func longGT(x, y *big.Int) bool { 135 return x.Cmp(y) > 0 136 } 137 138 func longFloat(f *Frame, o *Object) (*Object, *BaseException) { 139 flt, _ := new(big.Float).SetInt(&toLongUnsafe(o).value).Float64() 140 if math.IsInf(flt, 0) { 141 return nil, f.RaiseType(OverflowErrorType, "long int too large to convert to float") 142 } 143 return NewFloat(flt).ToObject(), nil 144 } 145 146 func hashBigInt(x *big.Int) int { 147 // TODO: Make this hash match that of cpython. 148 return hashString(x.Text(36)) 149 } 150 151 func longHex(f *Frame, o *Object) (*Object, *BaseException) { 152 val := numberToBase("0x", 16, o) + "L" 153 return NewStr(val).ToObject(), nil 154 } 155 156 func longHash(f *Frame, o *Object) (*Object, *BaseException) { 157 l := toLongUnsafe(o) 158 l.hashOnce.Do(func() { 159 // Be compatible with int hashes. 160 if numInIntRange(&l.value) { 161 l.hash = int(l.value.Int64()) 162 } 163 l.hash = hashBigInt(&l.value) 164 }) 165 return NewInt(l.hash).ToObject(), nil 166 } 167 168 func longIndex(_ *Frame, o *Object) (*Object, *BaseException) { 169 return o, nil 170 } 171 172 func longInt(f *Frame, o *Object) (*Object, *BaseException) { 173 if l := &toLongUnsafe(o).value; numInIntRange(l) { 174 return NewInt(int(l.Int64())).ToObject(), nil 175 } 176 return o, nil 177 } 178 179 func longInvert(z, x *big.Int) { 180 z.Not(x) 181 } 182 183 func longLE(x, y *big.Int) bool { 184 return x.Cmp(y) <= 0 185 } 186 187 func longLShift(z, x *big.Int, n uint) { 188 z.Lsh(x, n) 189 } 190 191 func longLong(f *Frame, o *Object) (*Object, *BaseException) { 192 if o.typ == LongType { 193 return o, nil 194 } 195 l := Long{Object: Object{typ: LongType}} 196 l.value.Set(&toLongUnsafe(o).value) 197 return l.ToObject(), nil 198 } 199 200 func longLT(x, y *big.Int) bool { 201 return x.Cmp(y) < 0 202 } 203 204 func longMul(z, x, y *big.Int) { 205 z.Mul(x, y) 206 } 207 208 func longMod(m, x, y *big.Int) { 209 z := &big.Int{} 210 longDivMod(x, y, z, m) 211 } 212 213 func longNative(f *Frame, o *Object) (reflect.Value, *BaseException) { 214 return reflect.ValueOf(toLongUnsafe(o).Value()), nil 215 } 216 217 func longNE(x, y *big.Int) bool { 218 return x.Cmp(y) != 0 219 } 220 221 func longNeg(z, x *big.Int) { 222 z.Neg(x) 223 } 224 225 func longNew(f *Frame, t *Type, args Args, _ KWArgs) (*Object, *BaseException) { 226 if t != LongType { 227 // Allocate a plain long and then copy its value into an 228 // object of the long subtype. 229 i, raised := longNew(f, LongType, args, nil) 230 if raised != nil { 231 return nil, raised 232 } 233 result := toLongUnsafe(newObject(t)) 234 result.value = toLongUnsafe(i).value 235 return result.ToObject(), nil 236 } 237 argc := len(args) 238 if argc == 0 { 239 return NewLong(big.NewInt(0)).ToObject(), nil 240 } 241 o := args[0] 242 baseArg := 10 243 if argc == 1 { 244 if slot := o.typ.slots.Long; slot != nil { 245 result, raised := slot.Fn(f, o) 246 if raised != nil { 247 return nil, raised 248 } 249 if !result.isInstance(LongType) { 250 format := "__long__ returned non-long (type %s)" 251 return nil, f.RaiseType(TypeErrorType, fmt.Sprintf(format, result.typ.Name())) 252 } 253 return result, nil 254 } 255 if raised := checkMethodArgs(f, "__new__", args, StrType); raised != nil { 256 return nil, raised 257 } 258 } else { 259 if raised := checkMethodArgs(f, "__new__", args, StrType, IntType); raised != nil { 260 return nil, raised 261 } 262 baseArg = toIntUnsafe(args[1]).Value() 263 if baseArg != 0 && (baseArg < 2 || baseArg > 36) { 264 return nil, f.RaiseType(ValueErrorType, "long() base must be >= 2 and <= 36") 265 } 266 } 267 s := strings.TrimSpace(toStrUnsafe(o).Value()) 268 if len(s) > 0 && (s[len(s)-1] == 'L' || s[len(s)-1] == 'l') { 269 s = s[:len(s)-1] 270 } 271 base := baseArg 272 if len(s) > 2 { 273 detectedBase := 0 274 switch s[:2] { 275 case "0b", "0B": 276 detectedBase = 2 277 case "0o", "0O": 278 detectedBase = 8 279 case "0x", "0X": 280 detectedBase = 16 281 } 282 if detectedBase != 0 && (baseArg == 0 || baseArg == detectedBase) { 283 s = s[2:] 284 base = detectedBase 285 } 286 } 287 if base == 0 { 288 base = 10 289 } 290 i := big.Int{} 291 if _, ok := i.SetString(s, base); !ok { 292 format := "invalid literal for long() with base %d: %s" 293 return nil, f.RaiseType(ValueErrorType, fmt.Sprintf(format, baseArg, toStrUnsafe(o).Value())) 294 } 295 return NewLong(&i).ToObject(), nil 296 } 297 298 func longNonZero(x *big.Int) bool { 299 return x.Sign() != 0 300 } 301 302 func longOct(f *Frame, o *Object) (*Object, *BaseException) { 303 val := numberToBase("0", 8, o) + "L" 304 if val == "00L" { 305 val = "0L" 306 } 307 return NewStr(val).ToObject(), nil 308 } 309 310 func longOr(z, x, y *big.Int) { 311 z.Or(x, y) 312 } 313 314 func longPos(z, x *big.Int) { 315 z.Set(x) 316 } 317 318 func longRepr(f *Frame, o *Object) (*Object, *BaseException) { 319 return NewStr(toLongUnsafe(o).value.Text(10) + "L").ToObject(), nil 320 } 321 322 func longRShift(z, x *big.Int, n uint) { 323 z.Rsh(x, n) 324 } 325 326 func longStr(f *Frame, o *Object) (*Object, *BaseException) { 327 return NewStr(toLongUnsafe(o).value.Text(10)).ToObject(), nil 328 } 329 330 func longSub(z, x, y *big.Int) { 331 z.Sub(x, y) 332 } 333 334 func longXor(z, x, y *big.Int) { 335 z.Xor(x, y) 336 } 337 338 func initLongType(dict map[string]*Object) { 339 dict["__getnewargs__"] = newBuiltinFunction("__getnewargs__", longGetNewArgs).ToObject() 340 LongType.slots.Abs = longUnaryOpSlot(longAbs) 341 LongType.slots.Add = longBinaryOpSlot(longAdd) 342 LongType.slots.And = longBinaryOpSlot(longAnd) 343 LongType.slots.Div = longDivModOpSlot(longDiv) 344 LongType.slots.DivMod = longDivAndModOpSlot(longDivAndMod) 345 LongType.slots.Eq = longBinaryBoolOpSlot(longEq) 346 LongType.slots.Float = &unaryOpSlot{longFloat} 347 LongType.slots.FloorDiv = longDivModOpSlot(longDiv) 348 LongType.slots.GE = longBinaryBoolOpSlot(longGE) 349 LongType.slots.GT = longBinaryBoolOpSlot(longGT) 350 LongType.slots.Hash = &unaryOpSlot{longHash} 351 LongType.slots.Hex = &unaryOpSlot{longHex} 352 LongType.slots.Index = &unaryOpSlot{longIndex} 353 LongType.slots.Int = &unaryOpSlot{longInt} 354 LongType.slots.Invert = longUnaryOpSlot(longInvert) 355 LongType.slots.LE = longBinaryBoolOpSlot(longLE) 356 LongType.slots.LShift = longShiftOpSlot(longLShift) 357 LongType.slots.LT = longBinaryBoolOpSlot(longLT) 358 LongType.slots.Long = &unaryOpSlot{longLong} 359 LongType.slots.Mod = longDivModOpSlot(longMod) 360 LongType.slots.Mul = longBinaryOpSlot(longMul) 361 LongType.slots.Native = &nativeSlot{longNative} 362 LongType.slots.NE = longBinaryBoolOpSlot(longNE) 363 LongType.slots.Neg = longUnaryOpSlot(longNeg) 364 LongType.slots.New = &newSlot{longNew} 365 LongType.slots.NonZero = longUnaryBoolOpSlot(longNonZero) 366 LongType.slots.Oct = &unaryOpSlot{longOct} 367 LongType.slots.Or = longBinaryOpSlot(longOr) 368 LongType.slots.Pos = longUnaryOpSlot(longPos) 369 // This operation can return a float, it must use binaryOpSlot directly. 370 LongType.slots.Pow = &binaryOpSlot{longPow} 371 LongType.slots.RAdd = longRBinaryOpSlot(longAdd) 372 LongType.slots.RAnd = longRBinaryOpSlot(longAnd) 373 LongType.slots.RDiv = longRDivModOpSlot(longDiv) 374 LongType.slots.RDivMod = longRDivAndModOpSlot(longDivAndMod) 375 LongType.slots.Repr = &unaryOpSlot{longRepr} 376 LongType.slots.RFloorDiv = longRDivModOpSlot(longDiv) 377 LongType.slots.RMod = longRDivModOpSlot(longMod) 378 LongType.slots.RMul = longRBinaryOpSlot(longMul) 379 LongType.slots.ROr = longRBinaryOpSlot(longOr) 380 LongType.slots.RLShift = longRShiftOpSlot(longLShift) 381 // This operation can return a float, it must use binaryOpSlot directly. 382 LongType.slots.RPow = &binaryOpSlot{longRPow} 383 LongType.slots.RRShift = longRShiftOpSlot(longRShift) 384 LongType.slots.RShift = longShiftOpSlot(longRShift) 385 LongType.slots.RSub = longRBinaryOpSlot(longSub) 386 LongType.slots.RXor = longRBinaryOpSlot(longXor) 387 LongType.slots.Str = &unaryOpSlot{longStr} 388 LongType.slots.Sub = longBinaryOpSlot(longSub) 389 LongType.slots.Xor = longBinaryOpSlot(longXor) 390 } 391 392 func longCallUnary(fun func(z, x *big.Int), v *Long) *Object { 393 l := Long{Object: Object{typ: LongType}} 394 fun(&l.value, &v.value) 395 return l.ToObject() 396 } 397 398 func longCallUnaryBool(fun func(x *big.Int) bool, v *Long) *Object { 399 return GetBool(fun(&v.value)).ToObject() 400 } 401 402 func longCallBinary(fun func(z, x, y *big.Int), v, w *Long) *Object { 403 l := Long{Object: Object{typ: LongType}} 404 fun(&l.value, &v.value, &w.value) 405 return l.ToObject() 406 } 407 408 func longCallBinaryTuple(fun func(z, m, x, y *big.Int), v, w *Long) *Object { 409 l := Long{Object: Object{typ: LongType}} 410 ll := Long{Object: Object{typ: LongType}} 411 fun(&l.value, &ll.value, &v.value, &w.value) 412 return NewTuple2(l.ToObject(), ll.ToObject()).ToObject() 413 } 414 415 func longCallBinaryBool(fun func(x, y *big.Int) bool, v, w *Long) *Object { 416 return GetBool(fun(&v.value, &w.value)).ToObject() 417 } 418 419 func longCallShift(fun func(z, x *big.Int, n uint), f *Frame, v, w *Long) (*Object, *BaseException) { 420 if !numInIntRange(&w.value) { 421 return nil, f.RaiseType(OverflowErrorType, "long int too large to convert to int") 422 } 423 if w.value.Sign() < 0 { 424 return nil, f.RaiseType(ValueErrorType, "negative shift count") 425 } 426 l := Long{Object: Object{typ: LongType}} 427 fun(&l.value, &v.value, uint(w.value.Int64())) 428 return l.ToObject(), nil 429 } 430 431 func longCallDivMod(fun func(z, x, y *big.Int), f *Frame, v, w *Long) (*Object, *BaseException) { 432 if w.value.Sign() == 0 { 433 return nil, f.RaiseType(ZeroDivisionErrorType, "integer division or modulo by zero") 434 } 435 return longCallBinary(fun, v, w), nil 436 } 437 438 func longCallDivAndMod(fun func(z, m, x, y *big.Int), f *Frame, v, w *Long) (*Object, *BaseException) { 439 if w.value.Sign() == 0 { 440 return nil, f.RaiseType(ZeroDivisionErrorType, "integer division or modulo by zero") 441 } 442 return longCallBinaryTuple(fun, v, w), nil 443 } 444 445 func longUnaryOpSlot(fun func(z, x *big.Int)) *unaryOpSlot { 446 f := func(_ *Frame, v *Object) (*Object, *BaseException) { 447 return longCallUnary(fun, toLongUnsafe(v)), nil 448 } 449 return &unaryOpSlot{f} 450 } 451 452 func longUnaryBoolOpSlot(fun func(x *big.Int) bool) *unaryOpSlot { 453 f := func(_ *Frame, v *Object) (*Object, *BaseException) { 454 return longCallUnaryBool(fun, toLongUnsafe(v)), nil 455 } 456 return &unaryOpSlot{f} 457 } 458 459 func longBinaryOpSlot(fun func(z, x, y *big.Int)) *binaryOpSlot { 460 f := func(_ *Frame, v, w *Object) (*Object, *BaseException) { 461 if w.isInstance(IntType) { 462 w = intToLong(toIntUnsafe(w)).ToObject() 463 } else if !w.isInstance(LongType) { 464 return NotImplemented, nil 465 } 466 return longCallBinary(fun, toLongUnsafe(v), toLongUnsafe(w)), nil 467 } 468 return &binaryOpSlot{f} 469 } 470 471 func longRBinaryOpSlot(fun func(z, x, y *big.Int)) *binaryOpSlot { 472 f := func(_ *Frame, v, w *Object) (*Object, *BaseException) { 473 if w.isInstance(IntType) { 474 w = intToLong(toIntUnsafe(w)).ToObject() 475 } else if !w.isInstance(LongType) { 476 return NotImplemented, nil 477 } 478 return longCallBinary(fun, toLongUnsafe(w), toLongUnsafe(v)), nil 479 } 480 return &binaryOpSlot{f} 481 } 482 483 func longDivModOpSlot(fun func(z, x, y *big.Int)) *binaryOpSlot { 484 f := func(f *Frame, v, w *Object) (*Object, *BaseException) { 485 if w.isInstance(IntType) { 486 w = intToLong(toIntUnsafe(w)).ToObject() 487 } else if !w.isInstance(LongType) { 488 return NotImplemented, nil 489 } 490 return longCallDivMod(fun, f, toLongUnsafe(v), toLongUnsafe(w)) 491 } 492 return &binaryOpSlot{f} 493 } 494 495 func longRDivModOpSlot(fun func(z, x, y *big.Int)) *binaryOpSlot { 496 f := func(f *Frame, v, w *Object) (*Object, *BaseException) { 497 if w.isInstance(IntType) { 498 w = intToLong(toIntUnsafe(w)).ToObject() 499 } else if !w.isInstance(LongType) { 500 return NotImplemented, nil 501 } 502 return longCallDivMod(fun, f, toLongUnsafe(w), toLongUnsafe(v)) 503 } 504 return &binaryOpSlot{f} 505 } 506 507 func longDivAndModOpSlot(fun func(z, m, x, y *big.Int)) *binaryOpSlot { 508 f := func(f *Frame, v, w *Object) (*Object, *BaseException) { 509 if w.isInstance(IntType) { 510 w = intToLong(toIntUnsafe(w)).ToObject() 511 } else if !w.isInstance(LongType) { 512 return NotImplemented, nil 513 } 514 return longCallDivAndMod(fun, f, toLongUnsafe(v), toLongUnsafe(w)) 515 } 516 return &binaryOpSlot{f} 517 } 518 519 func longRDivAndModOpSlot(fun func(z, m, x, y *big.Int)) *binaryOpSlot { 520 f := func(f *Frame, v, w *Object) (*Object, *BaseException) { 521 if w.isInstance(IntType) { 522 w = intToLong(toIntUnsafe(w)).ToObject() 523 } else if !w.isInstance(LongType) { 524 return NotImplemented, nil 525 } 526 return longCallDivAndMod(fun, f, toLongUnsafe(w), toLongUnsafe(v)) 527 } 528 return &binaryOpSlot{f} 529 } 530 531 func longShiftOpSlot(fun func(z, x *big.Int, n uint)) *binaryOpSlot { 532 f := func(f *Frame, v, w *Object) (*Object, *BaseException) { 533 if w.isInstance(IntType) { 534 w = intToLong(toIntUnsafe(w)).ToObject() 535 } else if !w.isInstance(LongType) { 536 return NotImplemented, nil 537 } 538 return longCallShift(fun, f, toLongUnsafe(v), toLongUnsafe(w)) 539 } 540 return &binaryOpSlot{f} 541 } 542 543 func longRShiftOpSlot(fun func(z, x *big.Int, n uint)) *binaryOpSlot { 544 f := func(f *Frame, v, w *Object) (*Object, *BaseException) { 545 if w.isInstance(IntType) { 546 w = intToLong(toIntUnsafe(w)).ToObject() 547 } else if !w.isInstance(LongType) { 548 return NotImplemented, nil 549 } 550 return longCallShift(fun, f, toLongUnsafe(w), toLongUnsafe(v)) 551 } 552 return &binaryOpSlot{f} 553 } 554 555 func longBinaryBoolOpSlot(fun func(x, y *big.Int) bool) *binaryOpSlot { 556 f := func(f *Frame, v, w *Object) (*Object, *BaseException) { 557 if w.isInstance(IntType) { 558 w = intToLong(toIntUnsafe(w)).ToObject() 559 } else if !w.isInstance(LongType) { 560 return NotImplemented, nil 561 } 562 return longCallBinaryBool(fun, toLongUnsafe(v), toLongUnsafe(w)), nil 563 } 564 return &binaryOpSlot{f} 565 } 566 567 func longRBinaryBoolOpSlot(fun func(x, y *big.Int) bool) *binaryOpSlot { 568 f := func(f *Frame, v, w *Object) (*Object, *BaseException) { 569 if w.isInstance(IntType) { 570 w = intToLong(toIntUnsafe(w)).ToObject() 571 } else if !w.isInstance(LongType) { 572 return NotImplemented, nil 573 } 574 return longCallBinaryBool(fun, toLongUnsafe(w), toLongUnsafe(v)), nil 575 } 576 return &binaryOpSlot{f} 577 } 578 579 func longPow(f *Frame, v, w *Object) (*Object, *BaseException) { 580 var wLong *big.Int 581 582 vLong := toLongUnsafe(v).Value() 583 if w.isInstance(LongType) { 584 wLong = toLongUnsafe(w).Value() 585 } else if w.isInstance(IntType) { 586 wLong = big.NewInt(int64(toIntUnsafe(w).Value())) 587 } else { 588 return NotImplemented, nil 589 } 590 591 if wLong.Sign() < 0 { 592 // The result will be a float, so we call the floating point function. 593 var vFloat, wFloat *Object 594 var raised *BaseException 595 596 vFloat, raised = longFloat(f, v) 597 if raised != nil { 598 return nil, raised 599 } 600 // w might be an int or a long 601 if w.isInstance(LongType) { 602 wFloat, raised = longFloat(f, w) 603 if raised != nil { 604 return nil, raised 605 } 606 } else if w.isInstance(IntType) { 607 wFloat = NewFloat(float64(toIntUnsafe(w).Value())).ToObject() 608 } else { 609 // This point should not be reachable 610 return nil, f.RaiseType(SystemErrorType, "internal error in longPow") 611 } 612 return floatPow(f, vFloat, wFloat) 613 } 614 615 return NewLong(big.NewInt(0).Exp(vLong, wLong, nil)).ToObject(), nil 616 } 617 618 func longRPow(f *Frame, v, w *Object) (*Object, *BaseException) { 619 if w.isInstance(LongType) { 620 return longPow(f, w, v) 621 } 622 if w.isInstance(IntType) { 623 wLong := NewLong(big.NewInt(int64(toIntUnsafe(w).Value()))).ToObject() 624 return longPow(f, wLong, v) 625 } 626 return NotImplemented, nil 627 } 628 629 func longDivMod(x, y, z, m *big.Int) { 630 z.QuoRem(x, y, m) 631 if m.Sign() == -y.Sign() { 632 // In Python the result of the modulo operator is always the 633 // same sign as the divisor, whereas in Go, the result is 634 // always the same sign as the dividend. Therefore we need to 635 // do an adjustment when the sign of the modulo result differs 636 // from that of the divisor. 637 m.Add(m, y) 638 // Relatedly, in Python the result of division truncates toward 639 // negative infinity whereas it truncates toward zero in Go. 640 // The fact that the signs of the divisor and the modulo result 641 // differ implies that the quotient is also negative so we also 642 // adjust the quotient here. 643 z.Sub(z, big.NewInt(1)) 644 } 645 }