A not-so-simple time calculation I'm struggling with some code that should be a very simple computation of a duration. The purpose of the code is to generate a random delay, constrained by an upper and lower limit. The reason I'm looking for advise here is that what should be a simple task, has turned into a behemoth of type conversions:

package main

import (
        "math/rand"
        "time"
)

func main() {
        // parameters, hardcoded for illustration purposes only
        tMin := float32(1.2)
        tMax := float32(2.7)

        // intention is approximately this:
        // delay := tMin + rand.Float32() * (tMax - tMin)

        delay := time.Duration((tMin + rand.Float32() * (tMax - tMin)) * float32(time.Second))

        time.Sleep(delay)
}


Questions:


Apart from rounding errors (which I'm happy to ignore here), does this code have any actual bugs that I missed?
I know that elegance is in the eye of the beholder, but is there any way to write this more elegantly? In particular, I'd like to reduce the number of required casts, preferably down to zero.
Encapsulate implementation details and any ugliness in a function. Readability is paramount.

For example, a more elegant solution,

package main

import (
    "math/rand"
    "time"
)

// delay returns a random delay, in nanoseconds,
// between min and max seconds.
func delay(min, max float64) time.Duration {
    // time doesn't go backwards
    if min &lt; 0 || min &gt; max {
        return 0
    }
    // delay in seconds
    d := min + rand.Float64()*(max-min)
    // delay in nanoseconds
    return time.Duration(d * float64(time.Second))
}

func main() {
    dMin, dMax := 1.2, 2.7

    time.Sleep(delay(dMin, dMax))
}


By design, Go is type safe. Conversions between diffent types must be explicit.

Unless you have a very large number of occurrences of a floating-point variable and you can tolerate the loss of precision, use type float64, not float32.




  behemoth : something of monstrous size. Merriam-Webster
  
  a behemoth of type conversions. uli


I only found a few type conversions in the code you posted.