Representing Binary or Hexadecimal Numbers
QUESTION: I have a number and I would like to see it expressed in both a binary and hexadecimal representation. How can I do that in IDL?
![]()
ANSWER: To express an integer value as a binary value you only have to use the binary data format, like this. (Thanks to Phillip Elson for pointing this obvious solution out to me.)
IDL> Print, 16748574L, FORMAT='(B0)'
111111111001000000011110
I sometimes prefer to use the Binary program from my Coyote Library to represent a binary number, because it has a couple of useful keywords for formatting the binary output in an easier to use format.
IDL> Print, Binary(16748574L, /SEPARATE)
0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 1 0 0 0 0 0 0 0 1 1 1 1 0
IDL> Print, Binary(16748574L, /SEPARATE, /COLOR)
1 1 1 1 1 1 1 1 1 0 0 1 0 0 0 0 0 0 0 1 1 1 1 0
Conversely, sometimes you might have a number represented in binary form (almost certainly as a string) and you would like to convert that number back to a decimal form. You can do so like this (also thanks to Phillip Elson).
IDL> number = 16748574L
IDL> binNumber = Binary(number, /COLOR)
IDL> Print, binNumber
1 1 1 1 1 1 1 1 1 0 0 1 0 0 0 0 0 0 0 1 1 1 1 0
IDL> dim = N_Elements(Byte(binNumber))
IDL> Print, Total( (Byte(Reverse(binNumber)) EQ 49) * 2L^Indgen(dim) ), FORMAT='(I0)'
16748574
![]()
Another Solution
Kevin Ivory (Kevin.Ivory@linmpi.mpg.de) offers another version of the Binary program, which he says:
... has the great advantage of additionally being able to show the binary representation of floats (this was quite important before IDL 5.1 got all these fancy keywords to the OPEN procedure). Something else I also concentrated on later in my own version, was to make the function work for arrays. [The Binary routine] now works for all numerical types and for arrays. It returns the same results on little and big-endian machines.
Here is the code, which has been modified by Ben Tupper to accept all manner of IDL integers, even 64-bit ones.
function binary, number
;+
; Name:
; binary
; Purpose:
; Returns the binary representation of a number of any numerical type.
; Argument:
; number scalar or array of numbers (any numerical type)
; Returns:
; Byte array with binary representation of numbers.
; Examples:
; Binary representation of 11b:
; IDL> print, binary(11b)
; 0 0 0 0 1 0 1 1
; Binary representation of pi (x86: Little-endian IEEE representation):
; IDL> print, format='(z9.8,5x,4(1x,8i1))', long(!pi,0), binary(!pi)
; 40490fdb 01000000 01001001 00001111 11011011 (x86 Linux)
; 0fdb4149 00001111 11011011 01000001 01001001 (Alpha OpenVMS)
; IDL> print, format='(8(1x,8i0))', binary(!dpi)
; 01000000 00001001 00100001 11111011 01010100 01000100 00101101 00011000
; Some first tests before type double was added:
; print, format='(2a6,4x,2z9.8,4x,8z3.2)', $
; !version.arch, !version.os, long(!dpi,0,2), byte(!dpi,0,8)
; x86 linux 54442d18 400921fb 18 2d 44 54 fb 21 09 40
; sparc sunos 400921fb 54442d18 40 09 21 fb 54 44 2d 18
; alpha vms 0fda4149 68c0a221 49 41 da 0f 21 a2 c0 68
; (Beginning with IDL 5.1, Alpha VMS uses IEEE representation as well.)
; Modification history:
; 19 Dec 1997 Originally a news posting by David Fanning.
; (Re: bits from bytes)
; 20 Dec 1997 "Complete" rewrite: eliminate loops.
; 22 Dec 1997 Bit shift instead of exponentiation, return byte
; array, handle input arrays.
; Think about double and complex types.
; 22 Sep 1998 Complete rewrite: reduce every numerical type to
; single bytes. Check that big and little endian machines
; return exactly the same results (if IEEE).
; 7 May 2003 Added newish data types, unsigned and long64. BT
;-
s = size(number)
type = s[s[0] + 1]
n_no = s[s[0] + 2]
; Numerical types: (will have to be completed if IDL adds double-long, ...)
; 1: byte (1-byte unsigned integer)
; 2: integer (2-byte signed integer)
; 3: long (4-byte signed integer)
; 4: floating-point (4-byte, single precision)
; 5: double-precision (8-byte, double precision)
; 6: complex (2x4-byte, single precision)
; 9: double-complex (2x8-byte, double precision)
; 12: uInt (2-byte, unsigned integer)
; 13: uLong (4-byte, unsigned integer)
; 14: Long64 (8-byte, signed integer)
; 15: uLong64 (8-byte, unsigned integer)
; Non-numerical types:
; 0: undefined, 7: string, 8: structure, 10: pointer, 11: object reference
; nbyt = [0, 1, 2, 4, 4, 8, 8, 0, 0, 16, 0, 0] ; number of bytes per type
; code = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
nbyt = [0, 1, 2, 4, 4, 8, 8, 0, 0, 16, 0, 0, 2, 4, 8, 8]
ntyp = nbyt[type]
if ntyp eq 0 then message, 'Invalid argument (must be numerical type).'
bits = [128, 64, 32, 16, 8, 4, 2, 1] ; = ishft(1b, 7-indgen(8))
; For correct array handling and byte comparison, 'number' and 'bits' require
; same dimensions -> numvalue and bitvalue
bitvalue = ((bits)[*, intarr(ntyp)])[*, *, intarr(n_no)]
little_endian = (byte(1, 0, 1))[0]
; In case of complex type and little endian machine, swap the two float values
; before the complete second dimension is reversed at returning.
if (type eq 6 or type eq 9) and little_endian then $ ; type complex
numvalue = reform((byte([number], 0, 1, ntyp/2, 2, n_no))$
[intarr(8), *, [1,0], *], 8, ntyp, n_no) $
else numvalue = (byte([number], 0, 1, ntyp, n_no))[intarr(8), *, *]
; On little endian machines, the second dimension of the return value must
; be reversed.
if little_endian and (type ne 1) then $
return, reverse((numvalue and bitvalue) ne 0, 2) else $
return, (numvalue and bitvalue) ne 0
end
![]()
Representing Hexadecimal Numbers
To represent hexadecimal numbers, use the Format keyword to the Print command with the "Z" format, like this:
IDL> values = Indgen(32)
IDL> Print, values, Format='( 16( Z2.2, x) )'
00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
![]()
Copyright © 1998 David W. Fanning
Last Updated 22 September 1998
