2013-03-20 36 views
6

Gần đây tôi đi qua những gì dường như câu đố logic của tôi của toán học trong một đoạn mãif ((123/1000)> 0) trả về false

if((123/1000) > 0) 

Đối với một số lý do, C# được tuyên bố rằng đây là sai nhưng nếu một người suy nghĩ một cách hợp lý, thì 0.123 lớn hơn 0.

Có lý do nào để tuyên bố rằng 0.123 nhỏ hơn 0 không?

Tôi đã đọc rằng sẽ có một vấn đề so sánh với đôi đó là cơ sở 2 và nó sẽ là tốt hơn để sử dụng số thập phân đó là cơ sở 10

Có thể ai đó soi sáng cho tôi?

+5

int/int luôn là int ... Hey đây là một ý tưởng hay về bài hát ... – ppeterka

+0

nếu ((123.0/1000.0)> 0.0) cho bạn thì sao? – Dutts

+0

một trong các toán hạng phải là số dấu phẩy động, bạn có thể chỉ định 'if ((123d/1000)> 0)' – Habib

Trả lời

15

sai lầm của bạn là bạn nghĩ rằng kết quả là 0.123 trong khi nó là 0 để thay thế.

C# (và nhiều ngôn ngữ khác giống C.) xác định rằng các hoạt động liên quan đến hai con số không thể thiếu luôn trả về một số nguyên, vì vậy 1 + 1 sẽ trở lại 2, không 2.03/2 sẽ trở lại 1, không 1.5. Phần phân đoạn trong trường hợp này chỉ đơn giản là bị loại bỏ, vì vậy nó luôn luôn tròn về phía không (tức là cho kết quả tích cực nó làm tròn xuống, cho những kết quả tiêu cực nó tròn lên).

Mặc dù điều này có thể phản tác dụng một chút vì lý do chính là đơn giản hóa ngôn ngữ/trình biên dịch, tốc độ thực thi (vì bạn không cần phải biết loại kết quả có), khả năng sử dụng toán tử như /= sẽ không hoạt động nếu kết quả là một loại khác) và di sản lịch sử và quán tính.

Để giải quyết điều này, bạn cần phải thực hiện ít nhất một trong các toán hạng của bạn một số dấu phẩy động (một trong những khác sẽ làm theo phù hợp tự động, như sẽ kết quả):

// either 
if (123.0/1000 > 0) 
// or 
if (123/1000.0 > 0) 
// or 
if (123.0/1000.0 > 0) 

Nếu bạn có các biến thay vào đó bạn có thể cần một thợ đúc chư (như bạn không thể chỉ đơn giản là thêm .0 :-)):

if ((double)a/b > 0) 

và những lời khuyên thông thường đúng ở đây cũng như: Khi lập trình, hiếm khi tin vào trực giác của bạn bởi vì máy tính là những cỗ máy kỳ lạ và ngôn ngữ lập trình đôi khi thậm chí st nhân viên kiểm lâm. In kết quả ở đâu đó hoặc gán nó vào một biến và kiểm tra trong trình gỡ rối sẽ cho bạn thấy rằng kỳ vọng của bạn bị tắt :-)

+0

Tôi sẽ chọn của bạn làm câu trả lời vì nó là toàn diện nhất. Cám ơn vì đã giải thích! –

0

Sử dụng này:

if((123.0/1000) > 0) 

Bạn đang cố gắng chia int bởi int. Vì vậy, bạn có được phân chia số nguyên. Nhưng bạn cần phải sử dụng gấp đôi.

Và nếu bạn muốn chia int biến và có được một sử dụng đôi này:

double doubleNum = (double)intNum1/(double)intNum2; 
9

123 và 1000 là các số nguyên, và kết quả là ít hơn 1 vì vậy nó làm tròn đến 0. Sử dụng này:

123.0/1000.0 > 0.0 

Và nó sẽ sử dụng độ chính xác gấp đôi, nghĩa là bạn có thể có một phần nhỏ!

4

Kể từ 1231000Int32, dẫn phải được Int32. Nhưng vì kết quả nhỏ hơn 1, kết quả được tự động làm tròn thành 0.

Bạn phải thực hiện ít nhất số này là số dấu phẩy động.

if(123.0/1000.0 > 0.0) 
{ 
    if((123.0/1000) > 0) 
    { 
     if((123/1000.0) > 0) 
     { 
      Console.WriteLine("True"); // Prints True 
     } 
    } 
} 

Đây là DEMO.

Kiểm tra câu hỏi này cũng Possible Loss of Fraction

+0

Vomit. Bạn đang vạch trần một người mới để mã hóa dòng đơn lẻ 4 lần 'if's. Vomit, và không có thêm bình luận –

+1

@KierenJohnstone Tôi đã viết nó như là một ví dụ với lời giải thích của tôi. Nhưng làm thế nào để bạn biết anh ta mới để viết mã? Nó chỉ là giả định. Và tôi tin rằng sử dụng lồng nhau 'if's' không chỉ dành cho các nhà phát triển có kinh nghiệm .. Tại sao leaset cũng không đáng bị downvote .. –

+1

Đó là một câu hỏi chất lượng thấp với lỗi chính tả, mã chất lượng thấp và bình luận chất lượng thấp. Tôi không thể đề nghị câu trả lời này, tôi chỉ có thể nhìn thấy sai sót. Do đó, downvote –

-1

Khi thực hiện phân chia chỉ với giá trị nguyên, kết quả cũng sẽ là số nguyên.

Nếu tôi nhớ chính xác phần sau dấu thập phân bị tước bỏ.

Vì vậy, bạn mã được biên dịch vào một cái gì đó như:.

a = int(123/1000) <--- evaluates to 0. 
if (a > 0) ....  <--- false 

Các giải pháp như mỗi câu trả lời @algreat là để buộc một trong các toán hạng để được tăng gấp đôi (bằng cách thêm .0 Điều này sẽ buộc kết quả là float . cũng

+1

-1: 'tầng' là một hàm C, và thêm' .0' không làm cho nó nổi, nó làm cho nó là một 'đôi' –

1

int/int là một int - có nghĩa là 123/10000 và không 0.123 như bạn mong đợi -

si nce 0 không lớn hơn 0, biểu thức đánh giá sai!

Việc sửa chữa là làm cho một trong những số nguyên như là một đôi -

if(123.0/1000 > 0) <- true 
if(123/1000.0 > 0) <- true 
if(123.0/1000.0 > 0) <- true 
2

Mặc dù điều này đã được trả lời, không có ai đã cho điểm tốt về xem cho vấn đề này, vì vậy tôi muốn làm cho nó rõ ràng hơn:

Nếu bạn là dividing hoặc multiplyingintfloat bạn sẽ nhận được kết quả như thế này:

int/int => int 
float/int => float 
int/float => float 
.210

vì vậy nếu bạn đang phân chia:

123/1000 => 0 (as there is no int number 0.123, it will then set to 0) 
123.0/1000 => 0.123 (this dividing is basically saying that I need a float result of dividing) 
123/1000.0 => 0.123 (this says the same as previous) 

Vì vậy, các nguyên tắc cơ bản là - nếu bạn đang sử dụng một loại đó là trên mức "thượng" mà một trong những nó được sử dụng, sau đó tính toán sẽ được dịch sang mà " loại "cha". Nhưng điều này không thể được nói chung, như thể loại nổi được sử dụng, nó sẽ luôn luôn được chuyển đến số float.Dưới đây là ví dụ:

long/int => long 
double/float => double 
double/int => double 

Và nếu bạn muốn có một câu trả lời cho câu hỏi của bạn, câu trả lời sẽ được đưa:

if(((float)123/1000) > 0) 

hoặc

if(((double)123/1000) > 0) 

Vì vậy, nó sẽ luôn tính số phao (số 0.123)