Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #16766 > unrolled thread

Hints for writing bit-twiddling code in Python

Started bySteven D'Aprano <steve+comp.lang.python@pearwood.info>
First post2011-12-07 04:03 +0000
Last post2011-12-07 11:33 +0200
Articles 4 — 4 participants

Back to article view | Back to comp.lang.python


Contents

  Hints for writing bit-twiddling code in Python Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-12-07 04:03 +0000
    Re: Hints for writing bit-twiddling code in Python Dan Stromberg <drsalists@gmail.com> - 2011-12-06 22:08 -0800
    Re: Hints for writing bit-twiddling code in Python Peter Otten <__peter__@web.de> - 2011-12-07 09:21 +0100
    Re: Hints for writing bit-twiddling code in Python Serhiy Storchaka <storchaka@gmail.com> - 2011-12-07 11:33 +0200

#16766 — Hints for writing bit-twiddling code in Python

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2011-12-07 04:03 +0000
SubjectHints for writing bit-twiddling code in Python
Message-ID<4edee584$0$13933$c3e8da3$76491128@news.astraweb.com>
I have some bit-twiddling code written in Java which I am trying to port 
to Python. I'm not getting the same results though, and I think the 
problem is due to differences between Java's signed byte/int/long types, 
and Python's unified long integer type. E.g. Java's >>> is not exactly 
the same as Python's >> operator, and a character coerced to a byte in 
Java is not the same as ord(char) in Python. (The Java byte is in the 
range -128...127, I think, while the ord in Python is in 0...255.)

Can anyone point me to some good resources to help me port the Java code 
to Python?

If it helps, the Java code includes bits like this:

long newSeed = (seed & 0xFFFFFFFFL) * 0x41A7L;
while (newSeed >= 0x80000000L) {
    newSeed = (newSeed & 0x7FFFFFFFL) + (newSeed >>> 31L);
    }
seed = (newSeed == 0x7FFFFFFFL) ? 0 : (int)newSeed;


which I've translated into:

newseed = (seed & 0xFFFFFFFF)*0x41A7
while (newseed >= 0x80000000):
    newseed = (newseed & 0x7FFFFFFF) + (newseed >> 31)
seed = 0 if newseed == 0x7FFFFFFF else newseed & 0xFFFFFFFF



-- 
Steven

[toc] | [next] | [standalone]


#16769

FromDan Stromberg <drsalists@gmail.com>
Date2011-12-06 22:08 -0800
Message-ID<mailman.3371.1323238116.27778.python-list@python.org>
In reply to#16766
On 12/6/11, Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote:
> I have some bit-twiddling code written in Java which I am trying to port
> to Python.:
>
> long newSeed = (seed & 0xFFFFFFFFL) * 0x41A7L;
> while (newSeed >= 0x80000000L) {
>     newSeed = (newSeed & 0x7FFFFFFFL) + (newSeed >>> 31L);
>     }
> seed = (newSeed == 0x7FFFFFFFL) ? 0 : (int)newSeed;

I suspect the problem lies somewhere other than the java and python
code you posted.

I'm having a bit of a time finding an input value of seed that gives
two different results, despite throwing some hard-feeling test cases
and lots of random values, using both a 32 bit and a 64 bit JVM.

I believe java likes to treat strings like Python 3, but if you use
"export LC_ALL=en_US.ISO-8859-1", then it'll behave a little more like
Python 2 in that strings have an 8 bit encoding (or at least act like
it) that's round-tripable.

If worse comes to worse, you could probably write some test harness
code for each of the java and python, and then feed them the same
inputs - to see which pieces differ and which don't.

[toc] | [prev] | [next] | [standalone]


#16774

FromPeter Otten <__peter__@web.de>
Date2011-12-07 09:21 +0100
Message-ID<mailman.3373.1323246133.27778.python-list@python.org>
In reply to#16766
Steven D'Aprano wrote:

> I have some bit-twiddling code written in Java which I am trying to port
> to Python. I'm not getting the same results though, and I think the
> problem is due to differences between Java's signed byte/int/long types,
> and Python's unified long integer type. E.g. Java's >>> is not exactly
> the same as Python's >> operator, and a character coerced to a byte in
> Java is not the same as ord(char) in Python. (The Java byte is in the
> range -128...127, I think, while the ord in Python is in 0...255.)
> 
> Can anyone point me to some good resources to help me port the Java code
> to Python?
> 
> If it helps, the Java code includes bits like this:
> 
> long newSeed = (seed & 0xFFFFFFFFL) * 0x41A7L;
> while (newSeed >= 0x80000000L) {
>     newSeed = (newSeed & 0x7FFFFFFFL) + (newSeed >>> 31L);
>     }
> seed = (newSeed == 0x7FFFFFFFL) ? 0 : (int)newSeed;
> 
> 
> which I've translated into:
> 
> newseed = (seed & 0xFFFFFFFF)*0x41A7
> while (newseed >= 0x80000000):
>     newseed = (newseed & 0x7FFFFFFF) + (newseed >> 31)
> seed = 0 if newseed == 0x7FFFFFFF else newseed & 0xFFFFFFFF

I think you need to take negative ints into account. Try adding

if seed & 0x80000000: # 2**31
    seed -= 0x100000000 # 2**32, two's complement

[toc] | [prev] | [next] | [standalone]


#16776

FromSerhiy Storchaka <storchaka@gmail.com>
Date2011-12-07 11:33 +0200
Message-ID<mailman.3375.1323250452.27778.python-list@python.org>
In reply to#16766
07.12.11 06:03, Steven D'Aprano написав(ла):
> long newSeed = (seed&  0xFFFFFFFFL) * 0x41A7L;
> while (newSeed>= 0x80000000L) {
>      newSeed = (newSeed&  0x7FFFFFFFL) + (newSeed>>>  31L);
>      }
> seed = (newSeed == 0x7FFFFFFFL) ? 0 : (int)newSeed;

seed = (seed & 0xFFFFFFFF) * 0x41A7 % 0x7FFFFFFF

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web