VTRyo Blog

一歩ずつ前に進むブログ

【Go】冪乗したときに指数表記しない

このようなお題があったとき、

入力として1つの整数 x が与えられます。 x の3乗の計算結果を1行に出力してください https://onlinejudge.u-aizu.ac.jp/courses/lesson/2/ITP1/1/ITP1_1_B

最初、こんなコードを書いた。

package main

import (
    "fmt"
    "math"
    "math/big"
)

func main() {
    var x int
    fmt.Scanln(&x)
    fmt.Println(calculate(x))
}

func calculate(x int) int64 {
    result := math.Pow(float64(x), float64(3))
    return int64(result)
}

100という大きめの数字を渡すと、次のように指数表記になった。ここは、1000000と表記してほしい。

$ go run ITP1_1_A/2.go
100
1e+06

※なお99だと指数表記にはならない…(なんで??)

$ go run ITP1_1_A/2.go
99
970299

大きな数字を扱うにはmath/big

pkg.go.dev

blog.amedama.jp

大きな数値を扱うためのデータ型や関数が用意されている。 整数型での自乗計算を行うには、Int.Exp関数を使用する。

ちなみにexpはexponentiation(冪乗)の略らしい。

package main

import (
    "fmt"
    "math/big"
)

func main() {
    var x int64
    fmt.Scanln(&x)
    fmt.Println(bigIntCalc(x))
}

func bigIntCalc(x int64) *big.Int {
    var constantInt int64
    constantInt = 3 // リファクタした

    b := new(big.Int)
    result := b.Exp(big.NewInt(x), big.NewInt(constantInt), nil)
    return result
}

指数表記を避けられた。

$ go run ITP1_1_A/2.go
100
1000000

余談: 与える数字が100以下だと指数表記にならない?

int64の最大値はもっと大きいので、指数表記になってしまう理由がわからなかった。
で、最初に使っていたmath.Pow関数はfloat64をreturnするので、こいつの最大値を越えていたのかと思って調べた。

pakcage main

func main() {
    fmt.Println(math.MaxFloat64)
}
$ go run ITP1_1_A/2.go
1.7976931348623157e+308

まあ確かに1.797~と大きくはないのだが、float64(99.9)などを与えて3で冪乗しても指数表記にはならなかったし、そのあたりうまく結論に到達しなかった。