計算結果が合わない理由を教えて下さい


Go言語で`1000000000000000000 × 1000000000000000000`という計算をしたら結果が  
`-5527149226598858752`になりました。  
単純に考えると`1000000000000000000000000000000000000`になると思うのですがなぜでしょう。

ちなみに実行したコードは以下のものです。

[code]

    package main
    import "fmt"
    
    func main() {
    
        i := 1000000000000000000
        fmt.Println(i*i)
    
    }
    
[/code]

Rubyで同じようにするとちゃんと`1000000000000000000000000000000000000`になるのですが、言語の仕様でしょうか。

[code]

    i = 1000000000000000000
    p i*i
    
[/code]




計算結果が int32 type もしくは int64 type の変数で扱うことができる整数の範囲を超えているためです。  
big.Int パッケージ [big - The Go Programming
Language](https://golang.org/pkg/math/big/) を使うことをお勧めします。

[code]

    package main
    
    import (
        "fmt"
        "math/big"
    )
    
    func main() {
        i := big.NewInt(1000000000000000000)
        fmt.Println(i.Mul(i, i))
    
        // Mmaximum values for int64 and uint64
        fmt.Printf(" MaxInt64 = %20d\n", int64(math.MaxInt64))
        fmt.Printf("MaxUint64 = %20d\n", uint64(math.MaxUint64))
    }
    
[/code]

なお、`math/const.go` に、各整数型における最大・最小値が定義されています。

[code]

    // Integer limit values.
    const (
        MaxInt8   = 1<<7 - 1
        MinInt8   = -1 << 7
        MaxInt16  = 1<<15 - 1
        MinInt16  = -1 << 15
        MaxInt32  = 1<<31 - 1
        MinInt32  = -1 << 31
        MaxInt64  = 1<<63 - 1
        MinInt64  = -1 << 63
        MaxUint8  = 1<<8 - 1
        MaxUint16 = 1<<16 - 1
        MaxUint32 = 1<<32 - 1
        MaxUint64 = 1<<64 - 1
    )
    
[/code]

注意点として、これらの定数は型が宣言されていません。そのため、使用に当たっては型変換が必要な場合があります。

[code]

    fmt.Println(math.MaxUint64)
    => constant 18446744073709551615 overflows int
    fmt.Println(uint64(math.MaxUint64))
    => 18446744073709551615
    
[/code]

