Я пытался решить старый вопрос:A + B без арифметических операторов, Python против C++
Написать функцию, которая добавить два [целые] числа A и B. Не следует использовать + или любую арифметику операторы.
Лучшее решение, как это, цитата из «LintCode-A+B Problem»:
Для + Ь в любой базе, мы можем рассматривать плюс как две части: 1. а + б без переноса; 2. перенос, генерируемый a + b. Затем a + b равен части 1 плюс часть 2. Если part1 + part2 генерирует больше переносов, мы можем повторить эту процедуру до тех пор, пока она не будет перенесена.
Я могу понять этот алгоритм, и все кажется хорошим, поэтому я проверил его на lintcode с кодом, вставленным ниже.
class Solution:
"""
@param a: The first integer
@param b: The second integer
@return: The sum of a and b
"""
def aplusb(self, a, b):
while b != 0:
carry = a & b
a = a^b
b = carry << 1
return a
Но удивительно, что он дал мне Time Limit Exceeded
ошибку в тесте [100, -100]
. Так что я побежал локально и печатать, а для каждого цикла:
(-8, 8)
(-16, 16)
(-32, 32)
(-64, 64)
(-128, 128)
(-256, 256)
(-512, 512)
(-1024, 1024)
(-2048, 2048)
(-4096, 4096)
(-8192, 8192)
(-16384, 16384)
(-32768, 32768)
(-65536, 65536)
(-131072, 131072)
...
Расчет правильно, поэтому я думаю, что этот алгоритм не работает для такого ввода, но когда я писал один и тот же алгоритм в C++, он просто работает :
class Solution {
public:
int aplusb(int a, int b) {
while (b!=0){
int carry = a & b;
a = a^b;
b = carry << 1;
}
return a;
}
};
Я не знаю, что следует задавать точно, в основном вопросы являются:
- Почему C++ дать правильный вывод
0
в то время как Python не делает? - Если я использую Python, как мне изменить этот алгоритм, чтобы он работал?
Подтвержденное целочисленное переполнение - неопределенное поведение. OP повезло, что версия C работает вообще. – Kevin
Не могли бы вы объяснить, что «все цифры, за исключением самых правых 31 цифр, рушится в один бит, так что остальные останутся на одном месте». более детально? Спасибо! – laike9m
@ laike9m: Возможно, было бы легче подумать об этом в противоположном направлении: когда вы конвертируете из двоичной цифры из числа int в двоичную цифру (2), вы должны подписать расширение: наиболее значимая цифра расширяется до бесконечно повторяющейся цифры. – Hurkyl