2015-01-12 68 views
5

khi nhân một bộ int và chuyển đổi kết quả thành một thời gian dài, tôi nhận được một câu trả lời khác trái ngược với khi tôi nhân một bộ tăng gấp đôi và chuyển đổi kết quả thành dài. ví dụ:Phép nhân trong lỗi C#

int a = 5; 
int b = 5; 
int c = 7; 
int d = 6; 
int ee = 6; 
int f = 8; 
int g = 9; 
int h = 6; 
int i = 6; 
int j = 4; 
int k = 8; 
int l = 9; 
int m = 5; 
long x = a * b * c * d * ee * f * g * h * i * j * k * l * m; 

double aa = 5; 
double ab = 5; 
double ac = 7; 
double ad = 6; 
double aee = 6; 
double af = 8; 
double ag = 9; 
double ah = 6; 
double ai = 6; 
double aj = 4; 
double ak = 8; 
double al = 9; 
double am = 5; 
long y = (long)(aa * ab * ac * ad * aee * af * ag * ah * ai * aj * ak * al * am); 

Bất cứ ai có thể cho tôi biết lý do điều này xảy ra? Cảm ơn bạn

+2

vì '' long'' và '' double' 'là những thứ khác nhau –

+2

Đôi và nổi __cannot__ giữ bất kỳ số nào với độ chính xác 100%, trừ khi nó là một sức mạnh của 2. Thay vào đó chúng chỉ giữ __approximations__ .. Đó là lý do chúng tôi có số thập phân – TaW

+1

Tôi khuyên bạn nên bật kiểm tra tràn trong cài đặt dự án của mình (tại ít nhất cho bản dựng gỡ lỗi). – CodesInChaos

Trả lời

13

Bạn đã có một số nguyên tràn, vì bất cứ khi nào bạn nhân hai int bạn có int: này được hiểu như là Int32 cho đến nay

a * b * c * d * ee * f * g * h * i * j * k * l * m 

và chỉ hơn chuyển đổi thành Int64 (long). Để sửa lỗi triển khai, hãy khai báo tất cả các biến ban đầu là long ví dụ:

long a = 5; 
    long b = 5; // actually, not necessary, since a * b will be long, but safer 
    long c = 7; 
    ... 
    long m = 5; 

    long x = a * b * c * d * ee * f * g * h * i * j * k * l * m; 
+5

Nó thậm chí không cần thiết để làm cho họ tất cả 'long'. Chỉ cần "buộc tính toán" để làm như vậy: 'long z = (dài) a * b * c * d * ee * f * g * h * i * j * k * l * m;' – ChrFin

+2

@ChrFin: bạn ' đúng, trong trường hợp này, về mặt kỹ thuật, * đối số đầu tiên chỉ * phải là loại 'Int64'; tuy nhiên, khi đối mặt với tràn số nguyên thì sẽ an toàn hơn để nói: "Tôi phải làm việc với các đại diện 64 bit" và chuyển tất cả các đối số nguyên thành 'Int64' –

+0

@DmitryBychenko: Cảm ơn bạn, tôi nghĩ nó giống như thế này. – Ka0s

5

Đó có thể là do kết quả phép nhân của bạn quá lớn để giữ trong Int32 - nhưng nó có thể được giữ ở mức gấp đôi.

Để có một chút cái nhìn cụ thể tại x và y trong hệ thập lục phân:

x = 0x000000007994b000
y = 0x000000057994b000

Một Int32 chỉ có thể giữ 8 giá trị hex thấp hơn. Đây là lý do tại sao x là số sai. 8 giá trị hex thấp nhất là chính xác, nhưng giá trị đầu được cắt bỏ.

2

tôi cho nó một tìm kiếm ngắn và chạy một số xét nghiệm ngay cả trên các kịch bản và tôi cũng tìm thấy những kết quả sau đây, ở định dạng kịch bản tôi thử nghiệm nó như là,

<script> 
     var a = 5; 
     var b = 5; 
     var c = 7; 
     var d = 6; 
     var ee = 6; 
     var f = 8; 
     var g = 9; 
     var h = 6; 
     var i = 6; 
     var j = 4; 
     var k = 8; 
     var l = 9; 
     var m = 5; 
     var x = a * b * c * d * ee * f * g * h * i * j * k * l * m; 
     var y = eval(a * b * c * d * ee * f * g * h * i * j * k * l * m); 
     document.writeln("RESULT X : " + x); 
     document.write("<br>"); 
     document.writeln("RESULT Y : " + y); 
    </script> 

và kết quả là 23514624000 cho cả xy, nhưng trong C# khi bạn cố gắng nhân tất cả các số nguyên và kết quả là một số nguyên được hình thành nhưng chúng tôi cũng biết rằng int.MAX = 2147483647 là ít hơn sau đó kết quả actuall, Vì vậy, kết quả khi gán cho long x= a * b * c * d * ee * f * g * h * i * j * k * l * m; nó cắt ngắn giá trị ban đầu, và ngược lại sult nó không phải là, nếu bạn muốn kết quả tương tự trong cả hai bạn có thể sử dụng đoạn mã sau,

int a = 5; 
int b = 5; 
int c = 7; 
int d = 6; 
int ee = 6; 
int f = 8; 
int g = 9; 
int h = 6; 
int i = 6; 
int j = 4; 
int k = 8; 
int l = 9; 
int m = 5; 
long x = (long)a * b * c * d * ee * f * g * h * i * j * k * l * m; 

double aa = 5; 
double ab = 5; 
double ac = 7; 
double ad = 6; 
double aee = 6; 
double af = 8; 
double ag = 9; 
double ah = 6; 
double ai = 6; 
double aj = 4; 
double ak = 8; 
double al = 9; 
double am = 5; 
long y = (long)(aa * ab * ac * ad * aee * af * ag * ah * ai * aj * ak * al * am); 
Console.WriteLine(x); 
Console.WriteLine(y); 
Console.ReadKey(); 

Bây giờ bạn sẽ nhận được kết quả tương tự tức là

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