big int giving me wrong results in equality - go

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

Related

Subtraction of large numbers golang

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

swap function not working in golang

Actually i just start to learn golang . In the beginning i think that = and := are same . But then i understand that there is some difference between this two .
I learned swap function in golnag
import "fmt"
func swap(x, y string) (string, string) {
return y, x
}
func main() {
a, b := swap("hello", "world")
fmt.Println(a, b)
}
But when i rewrite this function using var this is not working
package main
import "fmt"
func swap(x, y string) (string, string) {
return y, x
}
func main() {
var a, b string
a ="hello"
b="world"
swap(a, b)
fmt.Println(a, b)
}
what is the error in this program ?
Another solution is to use pointers:
package main
import "fmt"
func swap(x, y *string) {
*x, *y = *y, *x
}
func main() {
var a, b string
a ="hello"
b="world"
swap(&a, &b)
fmt.Println(a, b)
}
https://play.golang.org/p/-vxUMlaVmN
The reason is that in second case values returned from swap are ignored. SO nothing is changed.
Try: https://play.golang.org/p/uADEf5X15g
package main
import "fmt"
func swap(x, y string) (string, string) {
return y, x
}
func main() {
var a, b string
a = "hello"
b = "world"
a, b = swap(a, b) //// <----
fmt.Println(a, b)
}
To respond your initial question, you should assign the values returned by swap to a and b like so
a, b = swap(b, a)
Notice that this is simple assignment , without the : attached to the equal
also, instead of a swap function, you could just try inplace reassignment:
a, b = b, a
Variables declaration
var a string - declaration of a variable with null value
a := "spam" - declaration of a variable with a concrete value
func f(a, b string) (string, string) { - declaration of a function with value parameters. It means you have new variables with passed values as arguments each time you call a function.
func f(a, b *string) (*string, *string) { - declaration of a function with pointer arguments. In it's turn it means you have pointers to passed variables each time you call the function.
Also...
a := *string - declaration of a pointer variable.
*a - value of a pointer variable.
&a - pointer of a value
In-place swap
To swap in-place (without returning and reassigning) you should swap values between pointers.
func swap(a, b *string) {
*a, *b = *b, *a
}
p.s.
Take into account that strings is read-only slices of bytes. And slices are reference type it means that an array behind the sub-slices of a common array or slice is the same. It doesn't related to the question but should be considered in such cases.

Go Random number always return 168

I am a complete noob in regards to Go.
I am trying to make a an arbitrary function that returns two random numbers added together.
I have pasted my code below, and cannot figure out why it always returns 168!
package main
import(
"fmt"
"math/rand"
)
func add(x int, y int) int{
return x + y
}
var a int = rand.Intn(100)
var b int = rand.Intn(100)
func main() {
fmt.Println(add(a, b))
}
You have to specify seed to get different numbers. It is outlined in documentation:
Top-level functions, such as Float64 and Int, use a default shared
Source that produces a deterministic sequence of values each time a
program is run. Use the Seed function to initialize the default Source
if different behavior is required for each run.
And some reference about Seed
Seed uses the provided seed value to initialize the default Source to
a deterministic state. If Seed is not called, the generator behaves as
if seeded by Seed(1).
And you can see an example in the go cookbook:
rand.Seed(time.Now().Unix())
So wrapping up, you will have something like this:
package main
import(
"fmt"
"math/rand"
"time"
)
func add(x int, y int) int{
return x + y
}
func main() {
rand.Seed(time.Now().Unix())
var a int = rand.Intn(100)
var b int = rand.Intn(100)
fmt.Println(add(a, 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)
}

Resources