Strange behaviour of floating point constants in imported modules

John Machin sjmachin at lexicon.net
Mon May 23 08:20:28 EDT 2005


On Mon, 23 May 2005 12:39:00 +0200, Tomasz Lisowski
<tomlis at notmyisp.pl> wrote:

>Hi,
>
>We are distributing our Python application as the short main script (.py 
>file) and a set of modules compiled to the .pyc files. So far, we have 
>always treated .pyc files as portable between platforms, 

There is no guarantee at all that a .pyc file is good for any purpose
outside the machine that produced it.  In practice, however, you
*should* be able to rely on no surprises if you have the same platform
and the same version of Python; do you?

How did you transfer the .pyc files from one box to the other? A
Windows installer? A ZIP file? FTP using text mode? Plain-text
attachments to an e-mail message?


>but recently we 
>have discovered an annoying problem. In a module, there is the following 
>code fragment:
>
>Deg2Rad = math.pi/180.0
>angleEPS = 0.5
>angle0B = angleEPS*Deg2Rad
>
>which calculates 'angle0B' as the angle of a half of a degree, converted 
>to radians. The module has been compiled on an English Windows XP 
>machine, and then tested on a Polish Windows XP workstation.
>
>What was our astonishment, when various exceptions started to be raised 
>on a test machine (no problem on the original English-version Windows 
>XP). We have traced them to the fact, that both angleEPS and angle0B 
>were found to be ZERO (!!!), whereas in reality, angle0B is about 0.008. 

What evidence do you have? Have you disassembled the .pyc file on both
boxes and diff'ed the results? Have you computed checksums on both
boxes?

>And this all happened silently, without any error during the import of 
>the module!
>
>What's the reason of this error? I start thinking, that it may be 
>related to the fact, that the decimal point on the Enlish Windows XP is 
>the '.' character, and on the Polish one - ','.

This is *extremely* unlikely. Firstly, you are (I understand) talking
about a .pyc file, that was produced on an English Windows box.  Even
though the "180.0" and the "0.5" are visible as character strings in
the .pyc file, Python sure doesn't use the locale when it loads a .pyc
file.

Secondly, even if you are talking about a .py file, Python takes
absolutely no notice of the locale when it compiles the .py file.
Polish programmers write "0.5", not "0,5". Read the language reference
manual, section 2.4.5 -- it uses ".", not "whatever the decimal point
character might be in your locale". If it did depend on locale, you
would need a locale declaration at the top of the file, if one wanted
.py files to be portable internationally; ever seen or heard of such a
declaration?

Thirdly, if the dot was interpreted as something other than a decimal
point, then what? Perhaps assign a tuple (0, 5), or perhaps a syntax
error; zero is achieved under what conditions?

It's more likely that the .pyc file has been damaged somehow. AFAIK
they don't have checksums.

>
>Is there a good method to avoid this kind of problems? How to make such 
>distributed modules really portable?

Distribute source. 

HTH,

John




More information about the Python-list mailing list