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") }
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") }