2015-11-10 18 views
8

Tôi đang xây dựng một Lisp và tôi muốn các số nguyên 32 bit tự động chuyển sang số nguyên 64 bit nếu tính toán sẽ khiến chúng bị tràn. Và tương tự như vậy, đối với luồng tràn 64 bit, hãy chuyển sang số nguyên có kích thước tùy ý.Phát hiện tràn int đã ký trong Go

Vấn đề tôi có là tôi không biết cách "đúng" là phát hiện tràn số nguyên.

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

Làm cách nào để kiểm tra hiệu quả xem liệu c có bị tràn không?

Tôi đã xem xét luôn chuyển đổi thành giá trị 64 bit để thực hiện phép tính, sau đó giảm kích thước lại sau khi có thể, nhưng điều đó có vẻ tốn kém và lãng phí bộ nhớ cho thứ gì đó nguyên thủy và cốt lõi đối với ngôn ngữ đó.

+0

tôi nghi ngờ đấm bốc lên là đặt cược tốt nhất của bạn. Không có cơ chế trong ngôn ngữ chính xác để tiếp tục bổ sung nhanh chóng. – captncraig

+1

Tôi nghĩ rằng thêm 4 byte là gần như không đáng kể trong hầu hết các hệ thống hiện đại để chỉ sử dụng 64 bit vs 32 bit số nguyên trong hầu hết các tình huống (trường hợp ngoại lệ được thực hiện cho mảng lớn, vv). Đối với thời gian chạy tự động phát hiện tràn mà không cần đến lắp ráp, và nếu môi trường của bạn không ném một ngoại lệ, bạn có thể bắt, nó không phải là tầm thường. IMHO. – Alderin

+0

Chuyển đổi thành 64-bit * chỉ để tính toán * về cơ bản không có tác động bộ nhớ, vì bạn chỉ giữ một số lượng không đổi các giá trị có kích thước lớn tại một thời điểm. Đây là những gì, ví dụ, OpenJDK ['Math.multiplyExact (int, int)'] (http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/java /lang/Math.java#864). – user2357112

Trả lời

5

Ví dụ, để phát hiện 32-bit integer overflow cho Ngoài ra,

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) 
    } 
} 

Output:

integer overflow 2147483327 2147483327 0 
+0

Cảm ơn! Tôi nghĩ rằng tôi có thể có một giải pháp ngắn hơn, nhưng không chắc chắn nếu có những trường hợp cạnh mà nó không hoạt động: '((c d11wtq

Các vấn đề liên quan