April 2009 Archives

Big Numbers in Perl

|
A simple numerical overflow had been causing an error in my code for ages, and I just found it.  The problem arose from using numbers greater than 2^32 in Perl. I've become so used to 64-bit systems that I'd forgotten to check for it.

I use powers of 2 to encode values such as file formats into a single numerical field in MySQL (which briefly was SunSQL and is now OracleSQL?).  So I have code that looks like:

our %cat_formats = (
  2**1  => ['DICOM'],
  2**2  => ['NEMA'],
  2**3  => ['Analyze'],

and so on, adding the numbers together gives me a unique value, encoding combinations of values, which I can store in a BIGINT field in MySQL.  This was fine while I was listing 32 file formats or less, but I now list 36.  The test I had been using for matching a format-encoding value against the stored MySQL value is something like this, if I were testing for a value of 2.

  $ret = (($readfmt * 1) & 2) ? 1 : 0;

I multiply the value by 1 to be sure it's in a numerical context, and I pedantically set the return value to 1 or 0 for consistency with cases where I might want to set it to something else. 

Problem was, this was returning true whenever the stored value was greater than 2^32, and I use the value 2^34 to denote NIFTI format.  So whenever I was testing for a value of 2 (denoting DICOM, common), I was returning true for any program that could read NIFTI format (somewhat rarer).  Which lead to the FSL program being listed as the second highest ranked DICOM viewing program.  Now FSL is a fine program, but sadly it cannot read DICOM.

All I had to do to fix it was enable big numbers, and all was well.

use bignum;

About this Archive

This page is an archive of entries from April 2009 listed from newest to oldest.

March 2009 is the previous archive.

October 2009 is the next archive.

Find recent content on the main index or look in the archives to find all content.

Pages

  • blogimages
Powered by Movable Type 4.1