Неверная математика с 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".