Question about slight deviations when using integer division with large integers.
Why are the following two similar prints slightly different and how fix? >>> x = 0x739ad43ed636 >>> print(x + (-x) // 2048) 127046758190683 >>> print(x - x // 2048) 127046758190684 I'm working in an area where such deviations matter. It would nice to understand what is happening. Any help greatly appreciated. cs -- https://mail.python.org/mailman/listinfo/python-list
Re: Question about slight deviations when using integer division with large integers.
Thanks. I didn’t post new code. I was just referring back to original post. I need to duplicate the exact behavior of Java’s BigIntegers. I’m guessing difference between Java and Python is that Java BigIntegers do not switch to floor for negatives. Possible to tweak rounding of Python to be like Java? On Sun, Dec 30, 2018 at 11:24 PM Cameron Simpson wrote: > On 30Dec2018 21:14, Christian Seberino wrote: > >What is simplest way to make both those > >prints give same values? Any slicker way > >than an if statement? > > If your post had an attachment, be aware that the python-list list drops > all attachments - it is a text only list. Please paste your code > directly into your messages so that others can easily see it. > > Thanks, > Cameron Simpson > -- ___ Christian Seberino, Ph.D. Phone: (936) 235-1139 Email: cseber...@gmail.com ___ -- https://mail.python.org/mailman/listinfo/python-list
Re: Question about slight deviations when using integer division with large integers.
On 30Dec2018 23:33, Christian Seberino wrote: Thanks. I didn’t post new code. I was just referring back to original post. I think Ian looked up the first post on Google Groups, where your code was evident. The message was incomplete when it got here (the mailing list); I don't know why. I need to duplicate the exact behavior of Java’s BigIntegers. I’m guessing difference between Java and Python is that Java BigIntegers do not switch to floor for negatives. Possible to tweak rounding of Python to be like Java? Directly but hacking the int type? Probably not. What you probably want to do is to make a JavaBigInteger Python class which subclasses int, and change its operator implementation. Eg (totally untested): class JavaBigInteger(int): def __floordiv__(self, other): sign = 1 if self < 0: self = -self sign = -1 if other < 0: other = - other sign *= -1 result = self // other result *= sign return JavaBigOnteger(result) i.e. convert both operands to positive values, divide, adjust the sign. Some notes: Changing __floordiv__ needs to have matching changes to __divmod__ and __mod__ because they're supposed to be consistent. You probably also need to implement __truediv__, probably a lot like __floordiv__. There are also __rtruediv__ and __rfloordiv__ and __rmod__ and __rdivmod__. You need to turn whatever integers you're working with into JavaBigIntegers to make them use the new operator methods, and those methods should themselves return JavaBigIntegers to keep the behaviour: # x and y are ints x = 11 y = -2 print(x // y) # you already have x and y from somewhere, eg a file # they are ints, make new JavaBigIntegers from them xj = JavaBigInteger(x) yj = JavaBigInteger(y) print(xj // yj) Cheers, Cameron Simpson -- https://mail.python.org/mailman/listinfo/python-list
Re: Question about slight deviations when using integer division with large integers.
On Mon, 31 Dec 2018 at 09:00, Christian Seberino wrote: > > Thanks. I didn’t post new code. I was just referring back to original > post. I need to duplicate the exact behavior of Java’s BigIntegers. > > I’m guessing difference between Java and Python is that Java BigIntegers do > not switch to floor for negatives. Presumably Java BigInteger division consistently rounds to zero, whereas Python's // operator consistently rounds down. > Possible to tweak rounding of Python to be like Java? The correct answer is to have your developers understand the behaviour of the language they are using, and not assume it's like another language that they are more familiar with. But I appreciate that's not always easy. So what you are looking for are ways to help your developers avoid errors. Python doesn't have any way to change the behaviour of the // operator. I assume Java doesn't have a way to make BigInteger division round down, either? I doubt that using a custom-defined class in Python would help much - developers would likely not use it, unless they understood the reason for it (at which point, they wouldn't need it!). Code reviews, focusing on the use of the // operator, might be an answer (hopefully only needed short term until your developers understood the different behaviours of Java and Python). Or maybe some form of coding convention (all uses of // must be covered by unit tests that check all combinations of signs of the 2 operands). Or maybe a function java_style_divide(), that your conventions mandate must be used in preference to // Paul -- https://mail.python.org/mailman/listinfo/python-list
Re: Question about slight deviations when using integer division with large integers.
Thanks to all who helped. As was previously pointed out, many other languages use truncation rather than rounding for // division. Getting the behavior you want may be as easy as replacing // with the int() function >>> x = 9 ; y = 2 >>> x // y, -x // y, (-x) // y (4, -5, -5) >>> int(x / y), -int(x / y), int(-x / y) (4, -4, -4) Hope that helps. Chris -- https://mail.python.org/mailman/listinfo/python-list