Go Random number always return 168 - go

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

Related

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

What's wrong with this simple script?

I study functions, wrote a simple script for the textbook, and there were 2 errors.
package main
import "fmt"
func zero(x int) {
x = 0
return x
}
func main() {
x := 5
x = zero(x)
fmt.Println(x)
}
too many arguments to return (string return x)
How is "too many"? It's only one!
zero(x) used as value (string x = zero(x))
I don't understand what he says to me.
int in func
package main
import "fmt"
func zero(x int) int {
x = 0
return x
}
func main() {
x := 5
x = zero(x)
fmt.Println(x)
}
package main
import "fmt"
func zero(x int) int {
x = 0
return x
}
func main() {
x := 5
x = zero(x)
fmt.Println(x)
}
I believe this is closer to the original idea...
package main
import "fmt"
func zero(x *int) {
*x = 0
return
}
func main() {
x := 5
zero(&x)
fmt.Println(x)
}
too many means that your function is returning more values that the function signature specifies.
In your case, your function signature func zero(x *int), says that this function doesn't returns ANY params, and inside the function body, you're returning ONE value: return x. So 1 is too many for 0 expected. Exactly 1 more.
Then zero(x) used as value is telling you that you're calling a function that doesn't return ANY value, and you're trying to assign the non-existent return value to a variable: x = zero(x).
That's why the compiler tells you about using zero(x) as a value

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
}

Access one of the multiple result parameters return by a function in go

Here's the sample code (from tour.golang.org),
package main
import "fmt"
func split(sum int) (x, y int) {
x = sum * 4 / 9
y = sum - x
return
}
func main() {
x, _ := split(17)
fmt.Println(x)
}
I would like to know if it is possible to shorten the main function to just a single line. Logically there should be a way (might not look very elegant in this case though) to access only first result parameter returned from function and print it.
fmt.Println is a variadic function, so you can just pass the split function as a parameter:
func main() {
fmt.Println(split(17))
}
see it working in full here: http://play.golang.org/p/c1zkFVMe11

Generating Random Numbers in Go

I am trying to generate random numbers (integers) in Go, to no avail. I found the rand package in crypto/rand, which seems to be what I want, but I can't tell from the documentation how to use it. This is what I'm trying right now:
b := []byte{}
something, err := rand.Read(b)
fmt.Printf("something = %v\n", something)
fmt.Printf("err = %v\n", err)
But unfortunately this always outputs:
something = 0
err = <nil>
Is there a way to fix this so that it actually generates random numbers? Alternatively, is there a way to set the upper bound on the random numbers this generates?
Depending on your use case, another option is the math/rand package. Don't do this if you're generating numbers that need to be completely unpredictable. It can be helpful if you need to get results that are reproducible, though -- just pass in the same seed you passed in the first time.
Here's the classic "seed the generator with the current time and generate a number" program:
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
rand.Seed(time.Now().Unix())
fmt.Println(rand.Int())
}
crypto/rand provides only binary stream of random data, but you can read integers from it using encoding/binary:
package main
import "encoding/binary"
import "crypto/rand"
func main() {
var n int32
binary.Read(rand.Reader, binary.LittleEndian, &n)
println(n)
}
As of 1 april 2012, after the release of the stable version of the lang, you can do the following:
package main
import "fmt"
import "time"
import "math/rand"
func main() {
rand.Seed(time.Now().UnixNano()) // takes the current time in nanoseconds as the seed
fmt.Println(rand.Intn(100)) // this gives you an int up to but not including 100
}
You can also develop your own random number generator, perhaps based upon a simple "desert island PRNG", a Linear Congruential Generator. Also, look up L'Ecuyer (1999), Mersenne Twister, or Tausworthe generator...
https://en.wikipedia.org/wiki/Pseudorandom_number_generator
(Avoid RANDU, it was popular in the 1960's, but the random numbers generated fall on 15 hyperplanes in 3-space).
package pmPRNG
import "errors"
const (
Mersenne31 = 2147483647 // = 2^31-1
Mersenne31Inv = 1.0 / 2147483647.0 // = 4.656612875e-10
// a = 16807
a = 48271
)
// Each stream gets own seed
type PRNGStream struct {
state int
}
func PRNGStreamNew(seed int) *PRNGStream {
prng := (&PRNGStream{})
prng.SetSeed(seed)
return prng
}
// enforce seed in [1, 2^31-1]
func (r*PRNGStream) SetSeed(seed int) error {
var err error
if seed < 1 || seed > Mersenne31 {
err = errors.New("Seed OOB")
}
if seed > Mersenne31 { seed = seed % Mersenne31 }
if seed < 1 { seed = 1 }
r.state = seed
return err
}
// Dig = Park-Miller DesertIslandGenerator
// integer seed in [1, 2^31-1]
func (r*PRNGStream) Dig(seed int) float32 {
xprev := r.state // x[i-1]
xnext := (a * xprev) % Mersenne31 // x[i] = (a*x[i-1])%m
r.state = xnext // x[i-1] = x[i]
Ri := float32(xnext) * Mersenne31Inv // convert Ui to Ri
return Ri
}
func (r*PRNGStream) Rand() float32 {
r.state = (uint64_t)*r.state * Multby % 0x7fffffff
return float32(r.state) * Mersenne31Inv
}
A few relevant links:
https://en.wikipedia.org/wiki/Lehmer_random_number_generator
You might use this function to update your x[i+1], instead of the one above,
val = ((state * 1103515245) + 12345) & 0x7fffffff
(basically, different values of a, c, m)
https://www.redhat.com/en/blog/understanding-random-number-generators-and-their-limitations-linux
https://www.iro.umontreal.ca/~lecuyer/myftp/papers/handstat.pdf
https://www.math.utah.edu/~alfeld/Random/Random.html
https://learn.microsoft.com/en-us/archive/msdn-magazine/2016/august/test-run-lightweight-random-number-generation

Resources