preface

  • MulUintptr = MulUintptr = MulUintptr = MulUintptr = MulUintptr = MulUintptr
  • Returns false if it is out of bounds, true otherwise

, the code is as follows

Go /sys/MulUintptr

  
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package math

import "runtime/internal/sys"

const MaxUintptr = ^uintptr(0)

// MulUintptr returns a * b and whether the multiplication overflowed.
// On supported platforms this is an intrinsic lowered by the compiler.
func MulUintptr(a, b uintptr) (uintptr, bool) {
	if a|b < 1<<(4*sys.PtrSize) || a == 0 {
		return a * b, false
	}
	overflow := b > MaxUintptr/a
	return a * b, overflow
}
Copy the code

instructions

  • Didn’t understand the point is that a | b < 1 < < (4 * sys. PtrSize) | | a = = 0, see half a day did not understand
  • Checked on the net, only found usage, also did not find why write so
  • I finally figured it out in the car at night after work

Analysis of the

  • First of all, if a is equal to 0, there’s nothing to say, if a is equal to 0, then you can’t cross the boundary, right

  • Focus on the * * a | b < 1 < < (4 * sys. PtrSize) * *

  • Sys. PtrSize of 8 in 64 – bit machine, so the above code is equivalent to a | b < 1 < < 32

  • We know that the largest unsigned number in 64-bit computation is 2^64-1

  • If you look at 2^32 and 2^64, and you think of the function as multiplication, you get it

  • There are two conditions on which to agree

    • It’s very rare that you multiply two numbers that are really big, that are greater than or equal to 2^32
    • When a | b < 2 ^ 32, is a < 2 ^ 32, b < 2 ^ 32
      • Bit operations, I think you’re familiar with this
  • So if you want to know if two things multiplied together are greater than or equal to 2 to the 64, you just have to have both numbers less than 2 to the 32

  • This covers 99.9% of cases

  • Verflow := b > a

Translate the code as follows

Uintptr(a, b uintptr) (uintptr, bool) {uintptr (a, b uintptr) Return a * b, overflow}Copy the code