Пример #1
0
func number_divide(x, y Obj) Obj {
	xfx := (uintptr(unsafe.Pointer(x)) & fixnum_mask) == fixnum_tag
	yfx := (uintptr(unsafe.Pointer(y)) & fixnum_mask) == fixnum_tag
	if xfx && yfx {
		i1 := int(uintptr(unsafe.Pointer(x))) >> fixnum_shift
		i2 := int(uintptr(unsafe.Pointer(y))) >> fixnum_shift
		// A good optimizer will combine the div and mod into
		// one instruction.
		r, m := i1/i2, i1%i2
		if m == 0 && r > fixnum_min && r < fixnum_max {
			return Make_fixnum(r)
		} else {
			return wrap(big.NewRat(int64(i1), int64(i2)))
		}
	}

	if (!xfx && (uintptr(unsafe.Pointer(x))&heap_mask) != heap_tag) ||
		(!yfx && (uintptr(unsafe.Pointer(y))&heap_mask) != heap_tag) {
		panic("bad type")
	}

	if xfx {
		x = wrap(big.NewInt(int64(fixnum_to_int(x))))
	}
	if yfx {
		y = wrap(big.NewInt(int64(fixnum_to_int(y))))
		//return wrap(z.Div(vx,vy))
	}

	switch vx := (*x).(type) {
	case *big.Int:
		var z *big.Int = big.NewInt(0)
		switch vy := (*y).(type) {
		case *big.Int:
			return simpBig(z.Div(vx, vy))
		case *big.Rat:
			z := big.NewRat(1, 1)
			z.SetInt(vx)
			return simpRat(z.Quo(z, vy))
		default:
			panic("bad type")
		}
	case *big.Rat:
		z := big.NewRat(1, 1)
		switch vy := (*y).(type) {
		case *big.Int:
			z.SetInt(vy)
			return simpRat(z.Quo(vx, z))
		case *big.Rat:
			return simpRat(z.Quo(vx, vy))
		}
	}
	panic("bad type")
}
Пример #2
0
func number_multiply(x, y Obj) Obj {
	xfx := (uintptr(unsafe.Pointer(x)) & fixnum_mask) == fixnum_tag
	yfx := (uintptr(unsafe.Pointer(y)) & fixnum_mask) == fixnum_tag
	if xfx && yfx {
		i1 := int64(int(uintptr(unsafe.Pointer(x))))
		i2 := int64(int(uintptr(unsafe.Pointer(y))))
		r := (i1 >> fixnum_shift) * (i2 >> fixnum_shift)
		if r > int64(fixnum_min) && r < int64(fixnum_max) {
			return Make_fixnum(int(r))
		} else {
			return wrap(big.NewInt(r))
		}
	}

	if (!xfx && (uintptr(unsafe.Pointer(x))&heap_mask) != heap_tag) ||
		(!yfx && (uintptr(unsafe.Pointer(y))&heap_mask) != heap_tag) {
		panic("bad type")
	}

	if xfx {
		x = wrap(big.NewInt(int64(fixnum_to_int(x))))
	}
	if yfx {
		y = wrap(big.NewInt(int64(fixnum_to_int(y))))
	}

	switch vx := (*x).(type) {
	case *big.Int:
		var z *big.Int = big.NewInt(0)
		switch vy := (*y).(type) {
		case *big.Int:
			return simpBig(z.Mul(vx, vy))
		case *big.Rat:
			z := big.NewRat(1, 1)
			z.SetInt(vx)
			return simpRat(z.Mul(z, vy))
		default:
			panic("bad type")
		}
	case *big.Rat:
		z := big.NewRat(1, 1)
		switch vy := (*y).(type) {
		case *big.Int:
			z.SetInt(vy)
			return simpRat(z.Mul(vx, z))
		case *big.Rat:
			return simpRat(z.Mul(vx, vy))
		}
	}
	panic("bad type")
}