2013-04-09 29 views
77

Chỉ cần bắt đầu bằng Python, vì vậy đây có lẽ là lỗi của tôi, nhưng ...Toán sai với Python?

Tôi đang thử Python. Tôi thích sử dụng nó như một máy tính, và tôi đang dần dần làm việc thông qua một số hướng dẫn.

Tôi đã gặp phải điều gì đó kỳ lạ vào hôm nay. Tôi muốn tìm hiểu 2013 * 2013, nhưng tôi đã viết những điều sai trái và đã viết 2013 * 013, và nhận điều này:

>>> 2013*013 
22143 

Tôi đã kiểm tra với máy tính của tôi, và 22.143 là câu trả lời sai! 2013 * 13 được cho là 26169.

Tại sao Python cho tôi câu trả lời sai? Casio máy tính cũ của tôi không làm được điều này ...

+2

liên quan: http://stackoverflow.com/q/13013638/748858 – mgilson

+6

+1 để thực sự nhận thấy. Tôi biết đó là một số bát phân, nhưng nếu tôi không biết, bây giờ tôi nghĩ rằng 2013 * 13 là 22143. Làm sao bạn phát hiện ra đó là câu trả lời sai? – 11684

+11

Tôi đã học toán tinh thần trong một thời gian ở trường trung học, và tôi nghĩ rằng 22143 là một chút nhỏ hơn nó phải được. Vì vậy, tôi đã kiểm tra với máy tính đáng tin cậy của mình. –

Trả lời

137

Do số học bát phân, 013 thực sự là số nguyên 11.

>>> 013 
11 

Với hàng đầu zero, 013 được hiểu là một số cơ sở-8 và 1 * 8 + 3 * 8 = 11.

Lưu ý: hành vi này là changed in python 3. Dưới đây là một trích dẫn đặc biệt thích hợp từ PEP 3127

The default octal representation of integers is silently confusing to people unfamiliar with C-like languages. It is extremely easy to inadvertently create an integer object with the wrong value, because '013' means 'decimal 11', not 'decimal 13', to the Python language itself, which is not the meaning that most humans would assign to this literal.

+1

Eh? Ai sẽ sử dụng Octal? –

+7

Bất kỳ ai thỏa thuận với quyền hệ thống tệp sẽ sử dụng bát phân .. – wim

+14

@JamesElegan: Có lẽ đó là một lý do tại sao Python 3 làm cho cú pháp '0123' bất hợp pháp và luôn đòi hỏi' 0o123'. –

36

013 được một số nguyên bát phân đen (tương đương với số nguyên thập phân đen 11), do hàng đầu 0.

>>> 2013*013 
22143 
>>> 2013*11 
22143 
>>> 2013*13 
26169 

Nó là rất phổ biến (chắc chắn trong hầu hết các ngôn ngữ tôi quen thuộc) để có các số nguyên nguyên bát phân bắt đầu bằng 0 và các số nguyên hệ thập lục phân bắt đầu bằng 0x. Do sự nhầm lẫn chính xác mà bạn trải qua, Python 3 đặt ra một Lỗi Cú pháp:

>>> 2013*013 
    File "<stdin>", line 1 
    2013*013 
     ^
SyntaxError: invalid token 

và đòi hỏi một trong hai 0o hoặc 0O thay vì:

>>> 2013*0o13 
22143 
>>> 2013*0O13 
22143 
+0

Cảm ơn bạn đã trả lời! Tôi nghĩ rằng điều bát phân này là một chút khó hiểu, nhưng ít nhất bây giờ tôi biết về nó :) –

+3

Bạn đang rất hoan nghênh. Như đã lưu ý trong câu trả lời của tôi và @ wim, cộng đồng Python đang làm những gì họ có thể để giảm thiểu sự nhầm lẫn của newbie quanh octal literals với Python 3. Tuy nhiên, đó là một điều rất tốt cần lưu ý - bạn có thể chắc chắn rằng bạn sẽ gặp phải Các chữ số bát phân có tiền tố 0 một lần nữa, cho dù bằng Python 2.X hay một số ngôn ngữ khác. –

+2

PEP 3127 là một cách đọc khá thú vị về mặt này ... ví dụ: "một người dùng Python mới có thể bị hoang mang khi phát hiện trễ rằng con số của anh ấy không hoạt động đúng, chúng tôi có thể sửa nó bằng cách giải thích cho anh ta ngay lập tức rằng Python không thích số 0 đứng đầu (hy vọng với một thông điệp hợp lý!), hoặc chúng ta có thể ủy thác trải nghiệm giảng dạy này cho trình thông dịch JavaScript trong trình duyệt Internet Explorer và để anh ta cố gắng gỡ lỗi vấn đề của anh ta ở đó. " – wim

5

này thường chỉ mở rộng trên @ câu trả lời Wim của một chút, nhưng Python cho biết cơ sở của các chữ số nguyên sử dụng các tiền tố nhất định. Không có tiền tố, số nguyên được hiểu là nằm trong cơ sở-10. Với "0x", số nguyên sẽ được hiểu là int thập lục phân. Các đặc tả ngữ pháp đầy đủ là ở đây, mặc dù nó là một chút khôn lanh để hiểu nếu bạn không quen thuộc với ngữ pháp chính thức: http://docs.python.org/2/reference/lexical_analysis.html#integers

Bảng cơ bản nói rằng nếu bạn muốn có một giá trị dài (tức là một trong đó vượt quá khả năng của một bình thường int), viết số theo sau là chữ "L" hoặc "l"; nếu bạn muốn số của bạn được diễn giải bằng số thập phân, hãy viết số thường (không có số 0 đứng đầu); nếu bạn muốn nó được diễn giải trong bát phân, hãy thêm tiền tố bằng "0", "0o" hoặc "0O"; nếu bạn muốn nó trong hex, tiền tố nó với "0x"; và nếu bạn muốn nó trong nhị phân, tiền tố nó với "0b" hoặc "0B".

+0

Python dường như đang thêm L tự động, khi tôi nhập số thực sự lớn (như 9999999999999999999999999, nhưng không giống như 3333333333). Có lần nào tôi phải tự thêm nó không? –

+0

@JamesElegan chỉ khi bạn đang sử dụng phiên bản Python cũ điên khùng.Và trong Python 3, L đã biến mất hoàn toàn, cũng như tất cả các khác biệt giữa int và các kiểu dài. – lvc

+0

Python 2.7 không phải là điên rồ cũ, tôi lấy nó? Vì vậy, tôi không bao giờ cần phải thêm L. (Tôi tiếp tục nghe những điều tốt đẹp về Python 3, có lẽ tôi nên chỉ cần cài đặt và sử dụng?) –

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