2010-02-22 39 views
7

Tôi đang gặp sự cố kỳ lạ với C++ khi kiểu dữ liệu dài bị tràn lâu trước khi nó xảy ra. Những gì tôi đang làm (với thành công cho đến nay) là có các số nguyên hoạt động như phao nổi, do đó phạm vi [-32767,32767] được ánh xạ tới [-1.0,1.0]. Nơi mà nó tình cờ là với đối số lớn hơn đại diện nổi lớn hơn 1.0:C++ dài tràn quá sớm

inline long times(long a, long b) { 
    printf("a=%ld b=%ld ",a,b); 
    a *= b; 
    printf("a*b=%ld ",a); 
    a /= 32767l; 
    printf("a*b/32767=%ld\n",a); 
    return a; 
} 

int main(void) { 
    printf("%ld\n",times(98301l,32767l)); 
} 

Những gì tôi có được như đầu ra là:

a=98301 b=32767 a*b=-1073938429 a*b/32767=-32775 
-32775 

Vì vậy, lần (98301,32767) là tương tự như 3.0 * 1.0. Mã này hoạt động hoàn hảo khi các đối số với thời gian nhỏ hơn 32767 (1.0), nhưng không có bước trung gian nào với các đối số trên sẽ tràn 64 bit dài.

Bất kỳ ý tưởng nào?

+0

Bạn có thể chấp nhận câu trả lời sau đó không, nó giúp mọi người sẵn sàng giúp đỡ bạn trong tương lai. –

Trả lời

9

dài không nhất thiết phải 64 bit. hãy thử 'dài lâu' thay thế.

+0

Nó hoạt động! Cảm ơn tất cả những người đã đề xuất điều này, những gì kéo. Làm cho tôi đánh giá cao Java nhiều hơn nữa ... – rhodri

+0

@ rhodri: lâu dài thậm chí không nhất thiết phải 64-bit, bằng cách này (trên một số triển khai). Kiểm tra Boost Integer hoặc xem trình biên dịch của bạn có stdint.h hay không. – GManNickG

+1

@GMan: Đúng. Tuy nhiên, tiêu chuẩn C đảm bảo rằng 'long long' có * đủ phạm vi * cho một số nguyên 64 bit, và điều đó thường là đủ ... – sleske

2

Bạn có thể có độ dài 32 bit. Hãy thử sử dụng long long để thay thế.

98301 * 32767 = 3221028867, trong khi một tràn dài 32-bit tại 2147483648

4

Loại long không nhất thiết phải là 64 bit. Nếu bạn đang ở trên kiến ​​trúc 32 bit (ít nhất là trên MS Visual C++), loại long là 32 bit. Hãy khám phá với sizeof (long). Ngoài ra còn có loại dữ liệu long long có thể hữu ích.

2

Chuẩn C chỉ đảm bảo rằng long sẽ có ít nhất 32 bit (đây thực sự là trường hợp trên hầu hết các nền tảng 32 bit).

Nếu bạn cần 64 bit, hãy sử dụng long long. Nó được đảm bảo để giữ ít nhất 64 bit.