

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]


CC BY-SA 3.0
2015-01-12T15:03:47.583
4450
2015-01-12T17:03:57.940
5855
question
ruby go
計算結果が合わない理由を教えて下さい


計算結果が 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]


CC BY-SA 3.0
2015-01-12T15:14:11.480
4452
2015-01-12T17:03:57.940
2015-01-12T17:03:57.940
4450
answer


int は符号付き 32/64ビット整数ですから、あまり大きな値は扱えません。

  * int32 : -2147483648 ~ 2147483647
  * int64 : -9223372036854775808 to 9223372036854775807 (64ビット環境 の int)

これらより大きな範囲の数値を扱うときには、 "[math/big](https://golang.org/pkg/math/big/)"
パッケージを使います。

[code]

    package main
    import "fmt"
    import "math/big"
    
    func main() {
      biNum := big.NewInt(1000000000000000000)
      result := new(big.Int)
      result.Mul(biNum, biNum)
      fmt.Printf("%v * %v = %v\n", biNum, biNum, result)
    }
    
[/code]

出力 ([Online](https://play.golang.org/p/wIGt-VDfGT))

[code]

    1000000000000000000 * 1000000000000000000 = 1000000000000000000000000000000000000
    
[/code]

一方 Ruby の場合は、以下のように確認してみると、
コーダからは見えない部分で大きな数値用のオブジェクトとの使い分けがされていたことを知ることができます。

[code]

    p 1.0.class
    => Float
    p 1000000000000000000.class
    => Fixnum
    p 10000000000000000000.class
    => Bignum
    
    a = 1000000000000000000
    b = 10000000000000000000
    c = a * b
    
    p a.class
    => Fixnum
    p b.class
    => Bignum
    p c.class
    => Bignum
    
[/code]


CC BY-SA 3.0
2015-01-12T15:49:58.517
4454
2015-01-12T15:49:58.517
4978
4450
answer