Question about slight deviations when using integer division with large integers.

2018-12-31 Thread Christian Seberino
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.

2018-12-31 Thread Christian Seberino
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.

2018-12-31 Thread Cameron Simpson

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.

2018-12-31 Thread Paul Moore
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.

2018-12-31 Thread Christian Seberino
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