Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package main
- import (
- "fmt"
- "log"
- "slices"
- "strconv"
- "strings"
- )
- type Add struct {
- A, B, R int64
- }
- type Sub struct {
- A, B int64
- }
- func lenDiff(a, b int64, first string) int {
- switch first {
- case "a":
- var ad = len(fmt.Sprintf("%b", b)) - len(fmt.Sprintf("%b", a))
- if ad < 0 {
- return 0
- } else {
- return ad
- }
- case "b":
- var bd = len(fmt.Sprintf("%b", a)) - len(fmt.Sprintf("%b", b))
- if bd < 0 {
- return 0
- } else {
- return bd
- }
- default:
- return 0
- }
- }
- func toBit(a, b int64) (ab, bb string) {
- ab = fmt.Sprintf("%s%b", strings.Repeat("0", lenDiff(a, b, "a")), a)
- bb = fmt.Sprintf("%s%b", strings.Repeat("0", lenDiff(a, b, "b")), b)
- return
- }
- func rangeAdd(a, b string) []Add {
- var rem = make([]Add, len(a) + 1)
- var j int
- for i := len(a) - 1; i >= 0; i-- {
- ab, bb := int64(a[i] - '0'), int64(b[i] - '0')
- if ab == 1 && bb == 1 {
- rem[j].A = ab
- rem[j].B = bb
- rem[j + 1].R = 1
- }
- if (ab == 1 && bb == 0) || (ab == 0 && bb == 1) {
- rem[j].A = ab
- rem[j].B = bb
- }
- j++
- }
- for i, r := range rem {
- if (r.A == 1 && r.B == 0 && r.R == 1) || (r.A == 0 && r.B == 1 && r.R == 1) {
- rem[i + 1].R = 1
- }
- }
- return rem
- }
- func rangeSub(a, b string) []Sub {
- var rem = make([]Sub, len(a) + 1)
- var j int
- for i := len(a) - 1; i >= 0; i-- {
- ab, bb := int64(a[i] - '0'), int64(b[i] - '0')
- rem[j].A = ab
- if bb == 0 {
- rem[j].B = 1
- } else {
- rem[j].B = 0
- }
- j++
- }
- return rem
- }
- func ADD(a, b int64) int64 {
- var neg bool
- if a < 0 && b > 0 {
- if -a > b {
- return -SUB(-a, b)
- } else {
- return SUB(b, -a)
- }
- } else if a > 0 && b < 0 {
- if -b > a {
- return -SUB(-b, a)
- } else {
- return SUB(a, -b)
- }
- } else if a < 0 && b < 0 {
- neg = true
- }
- var rem []Add
- if neg {
- rem = rangeAdd(toBit(-a, -b))
- } else {
- rem = rangeAdd(toBit(a, b))
- }
- var adds []string
- for _, r := range rem {
- adds = append(adds, fmt.Sprint(r.A ^ r.B ^ r.R))
- }
- slices.Reverse(adds)
- res, err := strconv.ParseInt(strings.Join(adds, ""), 2, 0)
- if err != nil {
- log.Fatal(err)
- }
- if neg {
- return -int64(res)
- }
- return int64(res)
- }
- func compCalc(ai, bi int64) int64 {
- bi = ADD(bi, 1)
- var ab = ADD(ai, bi)
- var bfArr = strings.Split(fmt.Sprintf("%b", ab), "")
- bfArr = bfArr[1:]
- bfi, _ := strconv.ParseInt(strings.Join(bfArr, ""), 2, 0)
- return bfi
- }
- func SUB(a, b int64) int64 {
- var BgtA, NegAgtB, NegBgtA bool
- if a > 0 && b > 0 && a < b {
- BgtA = true
- } else if a > 0 && b < 0 {
- return ADD(a, -b)
- } else if a < 0 && b > 0 {
- return -ADD(-a, b)
- } else if a < 0 && b < 0 {
- if a > b {
- NegAgtB = true
- } else {
- NegBgtA = true
- }
- }
- var rem []Sub
- if BgtA {
- rem = rangeSub(toBit(b, a))
- } else if NegAgtB {
- rem = rangeSub(toBit(-b, -a))
- } else if NegBgtA {
- rem = rangeSub(toBit(-a, -b))
- } else {
- rem = rangeSub(toBit(a, b))
- }
- var aArr, bArr []string
- for _, r := range rem {
- bArr = append(bArr, fmt.Sprint(r.B))
- aArr = append(aArr, fmt.Sprint(r.A))
- }
- slices.Reverse(aArr)
- slices.Reverse(bArr)
- ai, _ := strconv.ParseInt(strings.Join(aArr, ""), 2, 0)
- bi, _ := strconv.ParseInt(strings.Join(bArr, ""), 2, 0)
- if BgtA {
- return -compCalc(bi, ai)
- } else if NegAgtB {
- return compCalc(bi, ai)
- } else if NegBgtA {
- return -compCalc(ai, bi)
- }
- return compCalc(ai, bi)
- }
Advertisement
Add Comment
Please, Sign In to add comment