How can I let a function randomly return either true or false in go

I want to have a function that I can call to get a random value true

or false

on every call:

  randBoolean() // true
  randBoolean() // false
  randBoolean() // false
  randBoolean() // true

      

How can I return a random boolean value?

+5


source to share


4 answers


You want some random information, and depending on its value, you can return true

half of your possible cases and false

the other half of the cases.

A very simple example using :rand.Float32()

math/rand

func rand1() bool {
    return rand.Float32() < 0.5
}

      

Remember to seed the package correctly math/rand

so that it differs every time you start your application using rand.Seed()

:

func main() {
    rand.Seed(time.Now().UnixNano())
    fmt.Println(rand1())
}

      

This is specified in the doc package math/rand

:

Use the Seed function to initialize the default source if different behavior is required for each run.

If you don't seed, the same pseudo-random information is returned every time you run the application.



Some options:

func rand2() bool {
    return rand.Int31()&0x01 == 0
}

func rand3() bool {
    return rand.Intn(2) == 0
}

      

And an interesting solution without using a package math/rand

. It uses the operator select

:

func rand9() bool {
    c := make(chan struct{})
    close(c)
    select {
    case <-c:
        return true
    case <-c:
        return false
    }
}

      

Explanation:

The operator select

selects one random case from those that can act without blocking. Since fetching from a closed channel can start immediately, one of the two cases will be randomly selected, returning either true

or false

. Note that, however, this is far from being entirely arbitrary, as it is not a requirement of the operator select

.

The channel can also be moved to a global variable, so there is no need to create one and close one in every call:

var c = make(chan struct{})

func init() {
    close(c)
}

func rand9() bool {
    select {
    case <-c:
        return true
    case <-c:
        return false
    }
}

      

+14


source


The easiest way is to create a random number and then take its modulo 2. Then, if it is 0, return true and if it is equal to 1, then return false.



+1


source


This function returns true if the random integer still returned false:

func randBool() bool{
    return rand.Int() % 2 == 0
}

      

+1


source


Here's another liner, doesn't require generating / seeding random numbers, etc., quite simple:

package main

import (
    "fmt"
    "time"
)

func main() {
    fmt.Println("Got random bool:", getRandBool())
}

func getRandBool() bool {
    now := time.Now()
    nowNano := now.Nanosecond()
    fmt.Println(nowNano)
    return now.UnixNano()%2 == 0
}

      

Edited after @icza's comments: time.Now () should return time with nanosecond precision, but on Windows 10 Pro 64-bit (and I've tried with go 1.8, and it may be the case for other Windows OSs as well) it always returns the time since less precision (perhaps microsecond), rounding the result so that it ends with xxxxx..00, and hence this function will always return true. I changed the function to see the result. Works great on Linux and should probably work on other Unix OSs as well. So either use this feature only after testing, or better not use if you need to deploy a Windows system. It's sad and hard to believe, but it's reality, poor Windows implementation. Thanks @icza for pointing out.

0


source







All Articles