Subtraction of large numbers golang - go

I did not think that I would have to write about it, but nowhere can I find at least an example of subtracting large numbers
So I have two numbers and I want to subtract them, the library says that there is only a limit on memory, however, when I try to subtract two 256-bit numbers I get an error.
Tell me what to do with it and how to solve it?
I began to study Go, everything seems to be so cool, however I constantly encounter similar questions. What's wrong.......
package main
import (
"fmt"
"math/big"
)
func main() {
a := big.NewInt(113792089237316195423570985008687907853269984665640564039457584007908834671645)
b := big.NewInt(20277110887056303803699431755396003735040374760118964734768299847012543114150)
c := big.NewInt(0).Sub(a, b)
fmt.Println("c =", c)
}
Output:
*prog.go:9:18: constant 113792089237316195423570985008687907853269984665640564039457584007908834671645 overflows int64
prog.go:10:18: constant 20277110887056303803699431755396003735040374760118964734768299847012543114150 overflows int64*
I'm using go version go1.12.4 linux/amd64
this code in playground:
https://play.golang.org/p/AY8Z8kkCRdg

Looks like you need to be using big.Int.SetString in your code. Here's a playground link, works there: https://play.golang.org/p/HvEke4g7e8V
For those who don't want to click a link:
package main
import (
"fmt"
"math/big"
)
func main() {
a, _ := new(big.Int).SetString("113792089237316195423570985008687907853269984665640564039457584007908834671645", 10)
b, _ := new(big.Int).SetString("20277110887056303803699431755396003735040374760118964734768299847012543114150", 10)
c := big.NewInt(0).Sub(a, b)
fmt.Println("c =", c)
}

mde.... .......
package main
import (
"fmt"
"math/big"
)
func main() {
i := new(big.Int)
i.SetString("113792089237316195423570985008687907853269984665640564039457584007908834671645", 10)
k := new(big.Int)
k.SetString("20277110887056303803699431755396003735040374760118964734768299847012543114150", 10)
c := big.NewInt(0).Sub(i, k)
fmt.Println("c =", c)
}
https://play.golang.org/p/AuGj9A93FbP

Related

How to make counter for big numbers

How to make counter that start from:
10000000000000000000000000000000000000000000000000000000000000000000000000000
and stop when it gets to:
10000000000000000000000000000000000000000000000000000000000000009999999999999
I have this code:
count,one := new(big.Int), big.NewInt(1)
count.SetString("10000000000000000000000000000000000000000000000000000000000000000000000000000",10)
I know this is easy for someone but Im newbi at GoLang so don't be angry if my question is stupid for you :)
Thanks anyway
There you go
package main
import (
"fmt"
"math/big"
)
func main() {
n1 := new(big.Int)
n1.SetString("100000000000000000000000000000000000000000000000000000000", 10)
n2 := new(big.Int)
n2.SetString("100000000000000000000000000000000000000000000000000000009", 10)
one := big.NewInt(1)
for i := n1; i.Cmp(n2) < 0; i.Add(i, one) {
//fmt.Println(i)
}
}
Just fit the right numbers into SetString.

big int giving me wrong results in equality

For some reason I'm getting the wrong result from big int when I test the equality even though the mod result is actually correct!
For example, I would like to calculate 2015%2 which results in 1.
When I use big int, I get false when I do this:
fmt.Println((test.Mod(big.NewInt(2015),big.NewInt(2)))==big.NewInt(1))
However, when I use regular int, I get true (which is the correct thing anyway):
fmt.Println(2015%2==1)
Am I supposed to do the equality differently when using big int?
Package big
import "math/big"
func NewInt
func NewInt(x int64) *Int
NewInt allocates and returns a new Int set to x.
func (*Int) Cmp
func (x *Int) Cmp(y *Int) (r int)
Cmp compares x and y and returns:
-1 if x < y
0 if x == y
+1 if x > y
The variables a and b are pointers: *big.Int. Use the Cmp method to compare values. For example,
package main
import (
"fmt"
"math/big"
)
func main() {
a := big.NewInt(42)
fmt.Printf("a: %[1]T %[1]p %[1]v\n", a)
b := big.NewInt(42)
fmt.Printf("b: %[1]T %[1]p %[1]v\n", b)
fmt.Println("pointers:", a == b) // compare pointers
fmt.Println("values: ", a.Cmp(b) == 0) // compare values
fmt.Println()
test := new(big.Int)
fmt.Println((test.Mod(big.NewInt(2015), big.NewInt(2))).Cmp(big.NewInt(1)) == 0)
}
Playground: https://play.golang.org/p/TH6UzceZ4y
Output:
a: *big.Int 0x1040a0c0 42
b: *big.Int 0x1040a0d0 42
pointers: false
values: true
true
Have a look at the (*int)Cmp function.
package main
import (
"fmt"
"math/big"
)
func main() {
a := big.NewInt(5)
b := big.NewInt(5)
fmt.Println(a == b)
fmt.Println(a.Cmp(b))
}

Calculating large exponentiation in Golang

I've been trying to calculating 2^100 in Golang. I understand the limit of numeric type and tried using math/big package. Here's what I've tried but I can't figure out why it doesn't work.
I've used computation by powers of two method to calculate the exponentiation.
package main
import (
"fmt"
"math/big"
)
func main() {
two := big.NewInt(2)
hundred := big.NewInt(50)
fmt.Printf("2 ** 100 is %d\n", ExpByPowOfTwo(two, hundred))
}
func ExpByPowOfTwo(base, power *big.Int) *big.Int {
result := big.NewInt(1)
zero := big.NewInt(0)
for power != zero {
if modBy2(power) != zero {
multiply(result, base)
}
power = divideBy2(power)
base = multiply(base, base)
}
return result
}
func modBy2(x *big.Int) *big.Int {
return big.NewInt(0).Mod(x, big.NewInt(2))
}
func divideBy2(x *big.Int) *big.Int {
return big.NewInt(0).Div(x, big.NewInt(2))
}
func multiply(x, y *big.Int) *big.Int {
return big.NewInt(0).Mul(x, y)
}
BigInt package allows you to calculate x^y in log time (for some reason it is called exp). All you need is to pass nil as a last parameter.
package main
import (
"fmt"
"math/big"
)
func main() {
fmt.Println(new(big.Int).Exp(big.NewInt(5), big.NewInt(20), nil))
}
If you are interested how to calculate it by yourself, take a look at my implementation:
func powBig(a, n int) *big.Int{
tmp := big.NewInt(int64(a))
res := big.NewInt(1)
for n > 0 {
temp := new(big.Int)
if n % 2 == 1 {
temp.Mul(res, tmp)
res = temp
}
temp = new(big.Int)
temp.Mul(tmp, tmp)
tmp = temp
n /= 2
}
return res
}
or play with it on go playground.
For example,
package main
import (
"fmt"
"math/big"
)
func main() {
z := new(big.Int).Exp(big.NewInt(2), big.NewInt(100), nil)
fmt.Println(z)
}
Output:
1267650600228229401496703205376
Since it's a power of two, you could also do a bit shift:
package main
import (
"fmt"
"math/big"
)
func main() {
z := new(big.Int).Lsh(big.NewInt(1), 100)
fmt.Println(z)
}
Output:
1267650600228229401496703205376
You are returning immediately if power % 2 == 0. Instead, you just want to get the result of base ** (power /2). Then multiply result * result, and if power is even then multiply base to that.
To compute 2^100
package main
import (
"fmt"
"math/big"
)
func main() {
n := big.NewInt(0)
fmt.Println(n.SetBit(n, 100, 1))
}
Playground
package main
import(
"fmt"
"math/big"
)
func main() {
bigx, power10 := new(big.Int), new(big.Int)
var x int64
bigx.SetInt64(x) //set x int64 to bigx
power10.Exp(big.NewInt(10), bigx, nil) //power10 *big.Int points to solution
str10 := power10.Text(10)
fmt.Printf(str10) // print out the number and check for your self
}

golang - modulus using math big package

Reading up the documentation - http://golang.org/pkg/math/big/
Mod sets z to the modulus x%y for y != 0 and returns z. If y == 0, a division-by-zero run-time panic occurs. Mod implements Euclidean modulus (unlike Go); see DivMod for more details.
10%4 = 2 but I get 8 with this (using the math/big package to do the same thing) - http://play.golang.org/p/_86etDvLYq
package main
import "fmt"
import "math/big"
import "strconv"
func main() {
ten := new(big.Int)
ten.SetBytes([]byte(strconv.Itoa(10)))
four := new(big.Int)
four.SetBytes([]byte(strconv.Itoa(4)))
tenmodfour := new(big.Int)
tenmodfour = tenmodfour.Mod(ten, four)
fmt.Println("mod", tenmodfour)
}
I most likely got something wrong. Where's the mistake?
It's because SetBytes is not doing what you think! Use SetInt64 instead.
ten := new(big.Int)
ten.SetBytes([]byte(strconv.Itoa(10)))
four := new(big.Int)
four.SetBytes([]byte(strconv.Itoa(4)))
fmt.Println(ten, four)
Result:
12592 52
And indeed, 12592%52 == 8
If you want to use numbers bigger than what int64 lets you manipulate, you can also use the SetString function:
n := new(big.Int)
n.SetString("456135478645413786350", 10)
Just an addition to julienc's answer, if you were to use SetBytes, you have to convert the number to bytes like this :
func int2bytes(num int) (b []byte) {
b = make([]byte, 4)
binary.BigEndian.PutUint32(b, uint32(num))
return
}
func main() {
ten := new(big.Int)
ten.SetBytes(int2bytes(10))
four := new(big.Int)
four.SetBytes(int2bytes(4))
fmt.Println(ten, four)
tenmodfour := new(big.Int)
tenmodfour = tenmodfour.Mod(ten, four)
fmt.Println("mod", tenmodfour)
}

How to reverse a binary number?

I'm newbie in Golan, this should be an easy question for experienced golang devs. I try to do the same test from Spotify to see how fast we can go in Golang :)
The usual bit-twiddling C solutions translate immediately to Go.
package main
import "fmt"
func BitReverse32(x uint32) uint32 {
x = (x&0x55555555)<<1 | (x&0xAAAAAAAA)>>1
x = (x&0x33333333)<<2 | (x&0xCCCCCCCC)>>2
x = (x&0x0F0F0F0F)<<4 | (x&0xF0F0F0F0)>>4
x = (x&0x00FF00FF)<<8 | (x&0xFF00FF00)>>8
return (x&0x0000FFFF)<<16 | (x&0xFFFF0000)>>16
}
func main() {
cases := []uint32{0x1, 0x100, 0x1000, 0x1000000, 0x10000000, 0x80000000, 0x89abcdef}
for _, c := range cases {
fmt.Printf("%08x -> %08x\n", c, BitReverse32(c))
}
}
Note: since 2013, you now have a dedicate math/bits package with Go 1.9 (August 2017).
And it does come with a collection of Reverse() and ReverseBytes() functions: no need to implement one anymore.
Plus, on most architectures, functions in this package are additionally recognized by the compiler and treated as intrinsics for additional performance.
The most straight-forward solution would be converting the bits into a number with strconv and then reversing the number by shifting the bits. I'm not sure how fast it would be, but it should work.
package main
import "fmt"
import "strconv"
func main() {
bits := "10100001"
bits_number := 8
number, _ := strconv.ParseUint(bits, 2, bits_number)
r_number := number - number // reserve type
for i := 0; i < bits_number; i++ {
r_number <<= 1
r_number |= number & 1
number >>= 1
}
fmt.Printf("%s [%d]\n", strconv.FormatUint(r_number, 2), r_number)
}
http://play.golang.org/p/YLS5wkY-iv

Resources