Неверная математика с Python?

Просто начинаем с Python, так что это, наверное, моя ошибка, но...

Я пытаюсь использовать Python. Мне нравится использовать его в качестве калькулятора, и я медленно работаю над некоторыми учебниками.

Сегодня я столкнулся с чем-то странным. Я хотел узнать 2013 2013, но я написал не то, и написал 2013 * 013, и получил это:

>>> 2013*013
22143

Я проверил с моим калькулятором, а 22143 - неправильный ответ! 2013 * 13 предполагается 26169.

Почему Python дает мне неправильный ответ? Мой старый калькулятор Casio не делает этого...

Ответ 1

Из-за восьмеричной арифметики 013 на самом деле является целым числом 11.

>>> 013
11

С начальным нулем 013 интерпретируется как номер базы-8 и 1 * 8 1 + 3 * 8 0= 11.

Примечание: это поведение было изменено в python 3. Вот особенно подходящая цитата из PEP 3127

По умолчанию восьмеричное представление целых чисел люди, незнакомые с C-подобными языками. Очень легко непреднамеренно создать целочисленный объект с неправильным значением, потому что "013" означает "десятичный номер 11", а не "десятичный 13", на язык Python само по себе, что не означает, что большинство людей назначили бы это буквальным.

Ответ 2

013 - восьмеричный целочисленный литерал (эквивалентный десятичному целочисленному литералу 11), из-за ведущего 0.

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

Очень часто (конечно, на большинстве языков, с которыми я знаком), чтобы восьмеричные целочисленные литералы начинались с 0, а шестнадцатеричные целочисленные литералы начинались с 0x. Из-за точной путаницы, которую вы испытали, Python 3 вызывает SyntaxError:

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

и вместо этого требуется либо 0o, либо 0o:

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

Ответ 3

Синтаксис "ведущего нуля" Python для восьмеричных литералов - это обычная информация:

Python 2.7.3
>>> 010
8

Синтаксис был изменен в Python 3.x http://docs.python.org/3.0/whatsnew/3.0.html#integers

Ответ 4

В основном это просто расширяется на @Wim, но Python указывает базу целых литералов с использованием определенных префиксов. Без префикса целые числа интерпретируются как находящиеся в базе-10. С "0x" целое число будет интерпретироваться как шестнадцатеричный int. Полная грамматическая спецификация здесь, хотя это немного сложно понять, если вы не знакомы с формальными грамматиками: http://docs.python.org/2/reference/lexical_analysis.html#integers

В таблице указано, что если вы хотите иметь длинное значение (то есть значение, превышающее емкость обычного int), напишите номер, за которым следует буква "L" или "l"; если вы хотите, чтобы ваш номер был интерпретирован в десятичной форме, напишите номер обычно (без ведущего 0); если вы хотите, чтобы он интерпретировался в восьмеричном, прикрепите его "0", "0o" или "0O"; если вы хотите его в шестнадцатеричном формате, прикрепите его "0x"; и если вы хотите его в двоичном формате, прикрепите его "0b" или "0B".