2 + 2 = 5

P

Paul Rubin

I just came across this (https://gist.github.com/1208215):

import sys
import ctypes
pyint_p = ctypes.POINTER(ctypes.c_byte*sys.getsizeof(5))
five = ctypes.cast(id(5), pyint_p)
print(2 + 2 == 5) # False
five.contents[five.contents[:].index(5)] = 4
print(2 + 2 == 5) # True (must be sufficiently large values of 2 there...)

Heh. The author is apparently anonymous, I guess for good reason.
 
S

Stefan Behnel

Paul Rubin, 04.07.2012 21:37:
I just came across this (https://gist.github.com/1208215):

import sys
import ctypes
pyint_p = ctypes.POINTER(ctypes.c_byte*sys.getsizeof(5))
five = ctypes.cast(id(5), pyint_p)
print(2 + 2 == 5) # False
five.contents[five.contents[:].index(5)] = 4
print(2 + 2 == 5) # True (must be sufficiently large values of 2 there...)

Heh. The author is apparently anonymous, I guess for good reason.

That's not portable, though. ;)

Stefan
 
M

Michael Ross

I just came across this (https://gist.github.com/1208215):

import sys
import ctypes
pyint_p = ctypes.POINTER(ctypes.c_byte*sys.getsizeof(5))
five = ctypes.cast(id(5), pyint_p)
print(2 + 2 == 5) # False
five.contents[five.contents[:].index(5)] = 4
print(2 + 2 == 5) # True (must be sufficiently large values of 2
there...)

Heh. The author is apparently anonymous, I guess for good reason.


Neat.

Playing with it, i'm wondering:


This:

import sys
import ctypes
pyint_p = ctypes.POINTER(ctypes.c_byte*sys.getsizeof(5))
five = ctypes.cast(id(5), pyint_p)
five.contents[five.contents[:].index(5)] = 4

print ( 2 + 2 == 5 )
print 5
print 5 - 2

put into a script and run prints:

True
4
3

while entered at the python prompt it prints:

True
4
2

??


Regards,
Michael
 
M

Mark Lawrence

I just came across this (https://gist.github.com/1208215):

import sys
import ctypes
pyint_p = ctypes.POINTER(ctypes.c_byte*sys.getsizeof(5))
five = ctypes.cast(id(5), pyint_p)
print(2 + 2 == 5) # False
five.contents[five.contents[:].index(5)] = 4
print(2 + 2 == 5) # True (must be sufficiently large values of 2 there...)

Heh. The author is apparently anonymous, I guess for good reason.

The author got confused trying to switch from imperial to metric numbers
or vice versa?
 
T

Thomas Jollans

I just came across this (https://gist.github.com/1208215):

import sys
import ctypes
pyint_p = ctypes.POINTER(ctypes.c_byte*sys.getsizeof(5))
five = ctypes.cast(id(5), pyint_p)
print(2 + 2 == 5) # False
five.contents[five.contents[:].index(5)] = 4
print(2 + 2 == 5) # True (must be sufficiently large values of 2 there...)

Heh. The author is apparently anonymous, I guess for good reason.

I'm reminded of the swap(a,b) function I wrote a couple of years back.

http://blog.jollybox.de/archives/62-python-swap
 
A

alex23

    print(2 + 2 == 5) # True (must be sufficiently large values of 2 there...)

I believe CCP use a variant of this approach in EvE with Stackless
Python.
 
E

Evan Driscoll

I just came across this (https://gist.github.com/1208215):

import sys
import ctypes
pyint_p = ctypes.POINTER(ctypes.c_byte*sys.getsizeof(5))
five = ctypes.cast(id(5), pyint_p)
print(2 + 2 == 5) # False
five.contents[five.contents[:].index(5)] = 4
print(2 + 2 == 5) # True (must be sufficiently large values of 2 there...)

Heh. The author is apparently anonymous, I guess for good reason.

Probably just nostalgic for old Fortran, which, supposedly, allowed you
to change the values of literals by passing them to a function by
reference and then modifying the value.

Evan



-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQEcBAEBAgAGBQJP9OJBAAoJEAOzoR8eZTzgPyQH/RYRdhNWV7XjjAg4SgNjt3wj
a0KSrKHg8TPKb2Sbj6M+t09UzE6dvwQMpUuO6oviue4pUgrPa9E0OK7TuWYi/3AA
J5GoC8xoWuy1t9+7Zu/fBC5ikuwPmDNOLhP0WgPCCdS35EZbNPvVg7FpvsidXeYZ
aFUFYi5VvJFmCPIGHFLqsomljMkavOde2ZtuPXSPgp4cBkb0sRxsMebN9xPjRWO9
5Sb6hchtwYZznJpc19WWCMSnIY+Ug30jsdP09dlr8SQf+PalOyBJbM9BoSaQ9NCG
ctFB/wDO6zamzr/Ba4vEA+9I6b4hsnjFe6l+1hlUgKBTxfbRqYoA4x6DGoz2Nb0=
=MvhR
-----END PGP SIGNATURE-----
 
T

Terry Reedy

I just came across this (https://gist.github.com/1208215):

import sys
import ctypes
pyint_p = ctypes.POINTER(ctypes.c_byte*sys.getsizeof(5))
five = ctypes.cast(id(5), pyint_p)
print(2 + 2 == 5) # False
five.contents[five.contents[:].index(5)] = 4
print(2 + 2 == 5) # True (must be sufficiently large values of 2
there...)

Heh. The author is apparently anonymous, I guess for good reason.


Neat.

Playing with it, i'm wondering:


This:

import sys
import ctypes
pyint_p = ctypes.POINTER(ctypes.c_byte*sys.getsizeof(5))
five = ctypes.cast(id(5), pyint_p)
five.contents[five.contents[:].index(5)] = 4

print ( 2 + 2 == 5 )
print 5
print 5 - 2

put into a script and run prints:

True
4
3

The compile-time optimizer computed the contant 5-2 in C.
while entered at the python prompt it prints:

True
4
2

It must not run for interactive input with the undisclosed version you
are running.

If I run the script in 3.3 Idle, I get the same output you got. If I
then enter '5-2' interactively, I still get 3. Maybe the constant folder
is always on now.
 
S

Steven D'Aprano

If I run the script in 3.3 Idle, I get the same output you got. If I
then enter '5-2' interactively, I still get 3. Maybe the constant folder
is always on now.

Yes, I believe constant folding is always on, since Python 2.4 if I
remember correctly. Somebody who cares more than me can possibly check
the "What's New" documents :)
 
H

Hans Mulder

Yes, I believe constant folding is always on, since Python 2.4 if I
remember correctly. Somebody who cares more than me can possibly check
the "What's New" documents :)

It's not a difference between 2.4 and 3.3; the difference is between
Idle and the command-line version of the interactive interpreter.

If I type the same code into Idle and the interactive interpreter
(both using 3.3alpha1), I get 3 in Idle and 2 in Terminal.

I don't quite understand why this difference exists.


Confused,

-- HansM
 
L

Laszlo Nagy

I just came across this (https://gist.github.com/1208215):

import sys
import ctypes
pyint_p = ctypes.POINTER(ctypes.c_byte*sys.getsizeof(5))
five = ctypes.cast(id(5), pyint_p)
print(2 + 2 == 5) # False
five.contents[five.contents[:].index(5)] = 4
print(2 + 2 == 5) # True (must be sufficiently large values of 2 there...)

Heh. The author is apparently anonymous, I guess for good reason.
five.contents[five.contents[:].index(5)] = 4
5 4
5 is 4
True

But this I don't understand:
6
 
M

MRAB

I just came across this (https://gist.github.com/1208215):

import sys
import ctypes
pyint_p = ctypes.POINTER(ctypes.c_byte*sys.getsizeof(5))
five = ctypes.cast(id(5), pyint_p)
print(2 + 2 == 5) # False
five.contents[five.contents[:].index(5)] = 4
print(2 + 2 == 5) # True (must be sufficiently large values of 2 there...)

Heh. The author is apparently anonymous, I guess for good reason.
five.contents[five.contents[:].index(5)] = 4
5 4
5 is 4
True

But this I don't understand:
4

5 is interned as 4, 0 is interned as 0, 4+0 is calculated as 4 and then
interned as 4.

5 is interned as 4, 1 is interned as 1, 4+1 is calculated as 5 and then
interned as 4.
5 is interned as 4, 2 is interned as 2, 4+2 is calculated as 6 and then
interned and 6.

Simple really! :)
 
S

Steven D'Aprano

It's not a difference between 2.4 and 3.3; the difference is between
Idle and the command-line version of the interactive interpreter.

If I type the same code into Idle and the interactive interpreter (both
using 3.3alpha1), I get 3 in Idle and 2 in Terminal.

I don't quite understand why this difference exists.

This difference exists because you are mucking about with implementation
details of Python, changing things which are not guaranteed by the
language, in ways that you are not supposed to change them. Since
changing the value of the int 2 into that of 3 is not supported, you can
hardly expect consistent behaviour. You're lucky that you don't get a
segfault. (In fact, if you keep playing around with it, you likely will
get a segfault.)

Idle does many things differently to the basic Python interpreter. This
should not surprise you. You should be surprised if it *does* work the
same in Idle and the basic Python interpreter.
 
A

Alexander Blinne

five.contents[five.contents[:].index(5)] = 4
5 4
5 is 4
True

That's surprising, because even after changing 5 to 4 both objects still
have different id()s (tested on Py2.7), so 5 is 4 /should/ still be
False (But isn't on my 2.7). But that's some implementation detail we
are not supposed to play with ;)
But this I don't understand:

6

That's easy:

5+0 is actually 4+0, because 5 == 4, so 5+0 gives 4.
5+1 is actually 4+1, which is 5, but 5 is again 4.
5+2 is 4+2 which is 6.

Greetings
 
H

Hans Mulder

five.contents[five.contents[:].index(5)] = 4
5 4
5 is 4 True

That's surprising, because even after changing 5 to 4 both objects still
have different id()s (tested on Py2.7), so 5 is 4 /should/ still be
False (But isn't on my 2.7). But that's some implementation detail we
are not supposed to play with ;)
False

This is when using the interactive interpreter; it may be different
in Idle.

-- HansM
 
E

Evan Driscoll

5+0 is actually 4+0, because 5 == 4, so 5+0 gives 4.
5+1 is actually 4+1, which is 5, but 5 is again 4.
5+2 is 4+2 which is 6.

Now all I can think is "Hoory for new math, new-hoo-hoo math" :)

Evan
 
A

Andrew Cooper

Now all I can think is "Hoory for new math, new-hoo-hoo math" :)

Evan

It wont do you a bit of good to read new math!

(My mind was on exactly the same track)

~Andrew
 
S

samuel.marks

On 05/07/2012 22:46, Evan Driscoll wrote:
> On 01/-10/-28163 01:59 PM, Alexander Blinne wrote:
>> 5+0 is actually 4+0, because 5 == 4, so 5+0 gives 4.
>> 5+1 is actually 4+1, which is 5, but 5 is again 4.
>> 5+2 is 4+2 which is 6.
>
> Now all I can think is "Hoory for new math, new-hoo-hoo math" :)
>
> Evan

It wont do you a bit of good to read new math!

(My mind was on exactly the same track)

~Andrew

+1
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top