Изменение поведения математического модуля Python для деления неположительных чисел - PullRequest
5 голосов
/ 22 мая 2011

Непоследовательное деление чисел довольно сильно отличается в языках программирования на С ++ и Python:

//c++:
11 / 3 = 3
11 % 3 = 2
(-11) / 3 = -3
(-11) % 3 = -2
11 / (-3) = -3
11 % (-3) = 2
(-11) / (-3) = 3
(-11) % (-3) = -2

Итак, как вы можете видеть, с ++ минимизирует частное.Тем не менее, python ведет себя так:

#python
11 / 3 = 3
11 % 3 = 2
(-11) / 3 = -4
(-11) % 3 = 1
11 / (-3) = -4
11 % (-3) = -1
(-11) / (-3) = 3
(-11) % (-3) = -2

Я не могу написать свою собственную функцию деления, похожую на c ++, потому что я буду использовать ее для проверки программ калькулятора c ++, а python не поддерживает инфиксные операторы.Могу ли я заставить Python вести себя как c ++ при простом делении целых чисел?Например, установить какой-нибудь флаг или что-то подобное?

Ответы [ 3 ]

3 голосов
/ 22 мая 2011

Как сказал Томас К., используйте math.fmod по модулю, или, если вы действительно хотите, вы можете определить его самостоятельно:

def cmod(x, y):
    return abs(x) % abs(y) * (1 if x > 0 else -1)

И эта функция должна эмулировать деление в стиле C:

def cdiv(x, y):
    return abs(x) / abs(y) * cmp(x, 0) * cmp(y, 0)

Вы сказали, что должны использовать операторы / и %. Это не возможно, так как вы не можете переопределить оператор для встроенных модулей. Однако вы можете определить свой собственный целочисленный тип и перегрузку операторов __div__ и __mod__.

2 голосов
/ 22 мая 2011

Нет флага, который можно установить, чтобы деление Python действовало как c ++.

Вы сообщили, что не можете написать свою собственную функцию деления, но если вы передумаете, вы можете сделать это:

def cpp_int_div(dividend, divisor):
    a, b = dividend, divisor
    sign = 1 if (a>0 and b>0) or (a<0 and b<0) else -1
    return (abs(a)/abs(b)) * sign

def cpp_int_mod(dividend, divisor): # or just use math.fmod  (from Thomas K)
    a, b = dividend, divisor
    sign = 1 if a>0 else -1
    return (abs(a)%abs(b)) * sign

Это показывает, что он действует в соответствии с вашей спецификацией:

print "11 / 3 = %d" % cpp_int_div(11,3)
print "11 %% 3 = %d" % cpp_int_mod(11,3)
print "(-11) / 3 = %d" % cpp_int_div(-11, 3)
print "(-11) %% 3 = %d" % cpp_int_mod(-11, 3)
print "11 / (-3) = %d" % cpp_int_div(11, -3)
print "11 %% (-3) = %d" % cpp_int_mod(11, -3)
print "(-11) / (-3) = %d" % cpp_int_div(-11, -3)
print "(-11) %% (-3) = %d" % cpp_int_mod(-11, -3)

Что дает:

11 / 3 = 3
11 % 3 = 2
(-11) / 3 = -3
(-11) % 3 = -2
11 / (-3) = -3
11 % (-3) = 2
(-11) / (-3) = 3
(-11) % (-3) = -2
0 голосов
/ 22 мая 2011

Вам также следует проверить модуль десятичный из стандартной библиотеки.

Десятичное число «основано на модели с плавающей запятой, которая была разработана с учетом потребностей людей и обязательно имеет первостепенный руководящий принцип - компьютеры должны обеспечивать арифметику, которая работает так же, как арифметика, которую люди изучают в школе». - выдержка из десятичной арифметической спецификации.

Тем не менее, результат

import decimal
decimal.divmod(-11, 3)
>>> (-4, 1)
...