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


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

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

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

>>> 2013*013
22143

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

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

4 77

4 ответа:

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

>>> 013
11

с нулем, 013 интерпретируется как основание-8 число и 1*81 + 3*80 = 11.

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

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

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 

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

Python 2.7.3
>>> 010
8

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

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

в таблица, по сути, говорит, что, если вы хотите длинное значение (т. е. то, что превышает возможности обычной инт), написать цифру, за которой следует буква "L" или "Л"; если вы хотите, чтобы ваш номер, чтобы быть интерпретированной в десятичной записи числа обычно (без начального 0); если вы хотите его толковать в восьмеричной, префикс с "0", "0о" или "0о"; если вы хотите его в hex, префикс с "0x"; и если вы хотите его в двоичном, него префикс "0b" или "0В".