sagantaf

IT関連の技術記事を書くブログ。

Go言語 - 指定した範囲の数値をintervalごとにリストにして返す

背景

指定した範囲でランダム値を返す方法はググれば見つかったけど、intervalごとに数値を生成する方法は見つからなかったので書いてみました。

中身

CreateNumList関数として作成。入力値も出力値もfloat64のtypeにしています。

// init ~ last の数値をintervalごとにリストにして返す
func CreateNumList(init, last, interval float64)[]float64{
    var nums []float64
    for i := init; i < last; {
        nums = append(nums, i)
        i = math.Round((i + interval)*100) / 100   // ※
    }
    return nums
}

引数として、initとlast、intervalを取得します。init以上last未満の値がintervalで指定した間隔でリストとして格納されます。

例えば

fmt.Println(CreateNumList(1,30,3))

とすると、

[1 4 7 10 13 16 19 22 25 28]

という出力を得られます。

※印の部分では、iを四捨五入してから更新しています。四捨五入をしないでi = i + intervalとすると、微小な計算誤差により、桁数の大きい数値が格納されてしまいます。

例えば、

CreateNumList(1,2,0.2)

としたときに、四捨五入をしないコードで実行すると、

[1 1.2 1.4 1.5999999999999999 1.7999999999999998 1.9999999999999998]

と表示されてしまいます。そのため、math.Round()を使って四捨五入しています。

ただし、math.Roundは整数になるまで四捨五入してしまうため、ここでは先に100倍して後から100で割ることで、小数点第二位での四捨五入を実現しています。

無限ループに注意

ここで注意点があります。

今回は、小数点第二位で四捨五入してから iの更新をしているため、もしintervalが0.001など小数点第二位よりも小さい値だった場合、iは更新されず無限ループになります。 (ここの判定ロジックを組むのは手間だったのでそのままにしています…)

まとめ

利用例とともにコード全体を記しておきます。

package main

import (
    "math"
    "fmt"
)

func CreateNumList(init, last, interval float64)[]float64{
    var nums []float64
    for i := init; i < last; {
        nums = append(nums, i)
        i = math.Round((i + interval)*100) / 100
    }
    return nums
}

func main(){
    fmt.Println(CreateNumList(1,30,3))
    fmt.Println(CreateNumList(10,12,0.2))
    fmt.Println(CreateNumList(1,1,1))
    // fmt.Println(calcSat.CreateNumList(1,2,0.005)) // 無限ループ
}

このコードの出力は

[1 4 7 10 13 16 19 22 25 28]
[10 10.2 10.4 10.6 10.8 11 11.2 11.4 11.6 11.8]
[]

です。