Variables
Click here to download in-class examples.
IDL has a number of different variable types. Here is an exhaustive list:
| Data Type | Description | How to Create | Size |
| Byte | Integer values from 0-255 | var = 5B var = byte(5) | 1 Byte |
| Integer | Integer values from -32768 - 32767 | var = 5 var = fix(5) | 2 Bytes |
| Unsigned Integer | Integer values from 0 - 65535 | var = 5U var = uint(5) | 2 Bytes |
| Long | Integer values from ~ -2billion - 2billion | var = 5L var = long(5) | 4 Bytes |
| Unsigned Long | Integer values from 0 - ~4billion | var = 5UL var = ulong(5) | 4 Bytes |
| 64 Bit Long | Integer values from -.5*2.0^64 - .5*2.0^64 | var = 5LL var = long64(5) | 8 Bytes |
| 64 Bit Unsigned Long | Integer values from 0 - 2.0^64 | var = 5ULL var = ulong64(5) | 8 Bytes |
| Floating Point | Floating point values in the range of 10^38 with ~7 digits of precision | var = 5.0 var = float(5) | 4 Bytes |
| Double Precision | Floating point values in the range of 10^308 with ~14 digits of precision | var = 5.0D var = double(5) | 8 Bytes |
| Complex | A real/imaginary pair of floating point precision numbers | var = complex(1.0, 0.0) | - |
| Double Precision Complex | A real/imaginary pair of double-precision numbers | var = dcomplex(1.0, 0.0) | - |
| String | A series of characters up to 2147483647 characters long | var = 'string!' var = "string!" var = string(52) | - |
In general you will probably only use the following variable types: Integer, Long, Float, Double, and strings. These form three distinct types of variables which are common to all program languages (integers, reals, and strings). It's important to be aware of the properties and limitations of these groups. Below, I summarize their properties. The following discussion applies to all programming languages, not just IDL.
Integers
In IDL bytes, integers, longs, long64s, and all of their unsigned varieties belong to the general group of integers. Integers in IDL (and all other programming languages) are exactly that - integers. They do not have any decimal information associated with them. The maximum number that can be stored in any integer is simply determined by the space allocated for that variable type in memory. So, an integer with a size of 2 bytes (16 bits) can store a value of up to 2.0^16 = 65536. A long integer with a size of 4 bytes (32 bits) can store a number as large as 2.0^32 = 4,294,967,296. In practice of course integers and longs can only store numbers up to half this size, because one bit is reserved for the sign of the integer - positive or negative. This is why all integer types have an unsigned equivilent. The unsigned integers can only be positive, but they can store up to their full range (twice as large as the signed varieties). In IDL if you try to assign a number to a variable that is larger than the maximum size allowed, it wraps around and becomes negative, clearly not a desired behavior. So always make sure you use an integer that is big enough to store the largest value you need to store.
Floats (reals)
In IDL floats and doubles belong to the family of variables generally refered to as floats or reals. Reals have a fractional as well as an integer part. In memory floats and doubles are actually stored in scientific notation, something like this:
var = .AAAAAAAx10^BB
So a real variable has three parts, a sign, a mantissa, and an exponent. This has an
**IMPORTANT** consequence. When a floating point variable is quoted to have 7 digits of precision, it is refering specifically to the above form. So if you examined two different numbers:
1234567.7654321
123456.7
The first number can't be represented precisely by IDL's 32 bit float. The second number is at the limit of the floating point precision. In memory IDL rewrites the number 1234567.7654321 as .12345677654321x10^7. Since it can only store 7 digits of precision, the entire second half of this variable is lost. So it is very important to understand that 7 digits of precision is refering to the total number of digits, not just the ones after the decimal place.
Another vital point regarding floating point precision that is often lost is the fact that the transformation from base 10 fractions to base 2 fractions is not 1 to 1. Since we count in base 10 and computers count in base 2, this can often create unexpected confusion. Consider for the moment the decimal value .05. In fractional form, this would be written as:
.05 = 0/10 + 5/100
This can be stored precisely. Look at the same number in base 2:
.05 = 0.0/2 + 0.0/4 + 0.0/8 + 0.0/16 + 1.0/32 + 1.0/64 + 0.0/128 + 0.0/256 + 1.0/512 + 1.0/1028 + 0.0/2048 + 0.0/4096 + 1.0/8192 + ...
In the end the floating point number .05 which is precise in base 10 is essentially irrational in base 2 and can't be represented precisely. This can create some problems when doing floating point comparisons and arithmetic. Since many numbers can't be stored exactly in base 2, numbers that you expect to be the same will often be different according to IDL. For your computer to consider two floating point numbers to be equal, every single bit has to be the same. So if two calculations happen to create two very similar numbers with slightly different binary representations, you computer will say they are not equal. Try entering the following line into an IDL command prompt:
if 1.05 ne 1.00 + .07 - .02 then print,'these are different!'
As the above discussion implies, IDL will typically believe that 1.05 is not equal to 1.00+.07-.02. This is because of the limitations of floating point precision. You simply can't expect floating point values to be perfectly exact. When comparing reals for equality, the best idea is typically to allow numbers within a certain range to be exact. Of course, this range will typically depend on the data set, but the fractional difference is typically small. Try something like this:
if abs( 1.05 - (1.00+.07-.02) ) lt .0001 then print,'They are the same!'
Remember though, the actual allowed deviation will depend on your data set and how precise you want your numbers to be.