5

Non-positive number division is quite different in c++ and python programming langugages:

//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

So, as you can see, c++ is minimizing quotient. However, python behaves like that:

#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

I can't code my own division function behaving like c++, because I'll use it for checking c++ calculator programs, and python does not support infix operators. Can I make python behaving like c++ while dividing integers in a simple way? For example, setting some flag or something like that?

karlicoss
  • 2,501
  • 4
  • 25
  • 29
  • `math.fmod` does modulo the same way as C. I don't think there's an easy equivalent for division. – Thomas K May 21 '11 at 21:27
  • 1
    If you want to know why Python breaks from C and C++ in the behavior of integer division, read this explanation from the creator of Python: http://python-history.blogspot.com/2010/08/why-pythons-integer-division-floors.html – Steven Rumbalski May 21 '11 at 22:07
  • Ruby integer division behaves like Python's, but in Ruby you can override the built-in behavior, so Ruby may be a better choice here. In general, modifying built-in behavior is a very bad idea. – Steven Rumbalski May 21 '11 at 22:29
  • @steven-rumbalski thanks for the article. I'll check if ruby can help me do that. – karlicoss May 21 '11 at 22:39
  • Or you could take the easy way out. Re-post your question but title it "Changing Ruby behaviour for non-positive numbers division". Anywhere your question says "Python" replace it with "Ruby". – Steven Rumbalski May 21 '11 at 22:44

3 Answers3

3

As Thomas K said, use math.fmod for modulo, or if you really want you can define it yourself:

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

And this function should emulate C-style division:

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

You said that you must use the / and % operators. This is not possible, since you can't override the operator for built-ins. You can however define your own integer type and operator overload the __div__ and __mod__ operators.

Steven Rumbalski
  • 44,786
  • 9
  • 89
  • 119
orlp
  • 112,504
  • 36
  • 218
  • 315
  • @nightcracker @thomas-k , thanks for response, but as I've already said, I can't use any functions, because in that case I'll have to convert all the expressions into prefix form. I want to use '/' and '%' operators, but make them behave the other way. – karlicoss May 21 '11 at 21:51
  • +1 Much more sophisticated and concise than my answer, but I can still suggest an improvement: `return abs(x) / abs(y) * (1 if x > 0 else -1)`. (Also note that your first `*` should have been '\'. – Steven Rumbalski May 21 '11 at 21:52
  • @Steven Rumbalski: While you were writing your comment I drastically changed my answer so that it's much cleaner and readable. – orlp May 21 '11 at 21:53
  • @karlicoss Since you can't use functions, and since you must use `/` and `%`, and since you can't get those to behave the way you want, your only option is to abort the project because it is impossible. – David Heffernan May 21 '11 at 21:54
  • @nightcracker wow, thanks! defining my own integer type looks like the easiest solution :) – karlicoss May 21 '11 at 22:06
  • 1
    @karlicoss Defining your own integer type still means you'll have to convert all your code! – David Heffernan May 21 '11 at 22:08
  • @nightcracker Temporary -1. Your mods don't work the same as karlicoss's examples. In his example if the dividend is negative the answer is negative. "-11 % -3" should be `-2` `cmod` returns `2`. "11 % -3" should be 2 `cmod` returns -2. (I don't have c++ to check which is the correct behavior, but I'm assuming karlicoss got it right).) – Steven Rumbalski May 21 '11 at 22:20
  • @steven-rumbalski , it's not the point. If I needed my own function, I could have written it myself :) I needed a way which didn't include converting arythmetic expressions in a prefix form. – karlicoss May 21 '11 at 22:32
  • @david-heffernan By this moment, I have no code, I'm thinking how to spend less time on it :) – karlicoss May 21 '11 at 22:33
  • I checked wikipedia's description of the modulo operator. C99, C#, and Java the result has the sign of the dividend. C++ and C90 the sign is implementation-defined when the dividend is negative. I'll bet that most implementations follow keeping the sign of the dividend as that is the practice of the c-style languages that have chosen to define it. – Steven Rumbalski May 21 '11 at 22:37
  • @karlicoss I know that's not the point, but it's still important that the details of the answer are correct. If you need this behavior you cannot use Python. I suggest Ruby as you can override the behavior of built-ins in Ruby. – Steven Rumbalski May 21 '11 at 22:39
  • @nightcracker That -1 was temporary because I thought you would correct your answer. Please fix it so I can give back a +1. – Steven Rumbalski May 21 '11 at 23:06
  • @nightcracker Edited it myself and erased my -1 to a 0. – Steven Rumbalski May 21 '11 at 23:57
2

There is no flag you can set to make python division to act like c++.

You advised that you can't code your own division function, but if you change your mind you can do this:

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

This shows that it acts according to your specification:

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)

Which gives:

11 / 3 = 3
11 % 3 = 2
(-11) / 3 = -3
(-11) % 3 = -2
11 / (-3) = -3
11 % (-3) = 2
(-11) / (-3) = 3
(-11) % (-3) = -2
Steven Rumbalski
  • 44,786
  • 9
  • 89
  • 119
0

You should also check out the decimal module from standard library.

Decimal “is based on a floating-point model which was designed with people in mind, and necessarily has a paramount guiding principle – computers must provide an arithmetic that works in the same way as the arithmetic that people learn at school.” – excerpt from the decimal arithmetic specification.

Yet, the result of

import decimal
decimal.divmod(-11, 3)
>>> (-4, 1)
Zaur Nasibov
  • 22,280
  • 12
  • 56
  • 83