2015-11-10 11 views
8

私はLispを構築していますが、32ビットの整数を計算すると64ビットの整数に自動的に切り替わります。同様に、64ビットオーバーフローの場合、任意の大きさの整数に切り替えます。Goで符号付き整数のオーバーフローが検出されました

問題は、整数オーバーフローを検出する方法が「正しい」ものではないことです。

a, b := 2147483647, 2147483647 
c := a + b 

cがオーバーフローしたかどうかを効率的に確認するにはどうすればよいですか?

私は計算を行うために常に64ビット値に変換し、可能であれば後でサイズを変更することを考えましたが、基本的な算術としての言語にとっては原始的で核心であるものにとっては高価でメモリが無駄に見えます。例えば

+0

を私はボクシングのアップは、あなたの最善の策であると思います。言語の中に正確に追加を速くする仕組みはありません。 – captncraig

+1

私は余分な4バイトはほとんどの現代のシステムではほとんどの状況(大規模な配列などで作られた例外)で32ビットの整数を使用するだけで無視できると思います。ランタイム自動検出では、アセンブリに頼らずにオーバーフローを検出できますが、環境によって例外がスローされない場合でも、それは簡単なことではありません。私見では。 – Alderin

+0

計算のためだけに64ビット*に変換することは、一度に一定の数のアップサイズ値を保持しているので、基本的にメモリの影響はありません。これは、例えば、OpenJDKの['Math.multiplyExact(int、int)'](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/java)です。 /lang/Math.java#864)があります。 – user2357112

答えて

5

、追加のため

package main 

import (
    "errors" 
    "fmt" 
    "math" 
) 

var ErrOverflow = errors.New("integer overflow") 

func Add32(left, right int32) (int32, error) { 
    if right > 0 { 
     if left > math.MaxInt32-right { 
      return 0, ErrOverflow 
     } 
    } else { 
     if left < math.MinInt32-right { 
      return 0, ErrOverflow 
     } 
    } 
    return left + right, nil 
} 
func main() { 
    var a, b int32 = 2147483327, 2147483327 
    c, err := Add32(a, b) 
    if err != nil { 
     // handle overflow 
     fmt.Println(err, a, b, c) 
    } 
} 

出力32ビット整数オーバーフローを検出する:

integer overflow 2147483327 2147483327 0 
+0

ありがとう!私はより短い解を持つかもしれないが、それがうまくいかない場合があるかどうかは分からないと思う: '((c d11wtq

関連する問題