Sonntag, 5. Januar 2014

Flags mit GNU bc aufschlüsseln

Mehrmals schon hatte ich beim Testen oder Debuggen das Bedürfnis, die Bestandteile eines iflag-Wertes in seine einzelnen Optionen zu zerlegen, ohne ihn erst (z.B. im Kopf) binär umrechnen zu müssen.

Für solche kleinen Rechnereien empfiehlt sich bc(1), ursprünglich ein kleiner Rechner für die Kommandozeile, und von Entwicklern weiter aufgepeppt. bc(1) kann auch Funktionen, hat Kontrollstrukturen und Schleifen, kennt Arrays, symbolische Variable usw.

Hier mein Tool iflag.

#!/usr/bin/bc -q 

scale = 0

print "iflag = "
iflag = read()

define bit( i, p ) {
  return ((i/p) % 2 == 1)
  }

if (bit( iflag, 1)) print "seflg_jpleph\n";
if (bit( iflag, 2)) print "seflg_swieph\n";
if (bit( iflag, 4)) print "seflg_moseph\n" ;
if (bit( iflag, 8)) print "seflg_helctr\n";
if (bit( iflag, 16)) print "seflg_truepos\n";
if (bit( iflag, 32)) print "seflg_j2000\n";
if (bit( iflag, 64)) print "seflg_nonut\n";
if (bit( iflag, 128)) print "seflg_speed3\n";
if (bit( iflag, 256)) print "seflg_speed\n";
if (bit( iflag, 512)) print "seflg_nogdefl\n";
if (bit( iflag, 1024)) print "seflg_noaberr\n";
if (bit( iflag, (2*1024))) print "seflg_equatorial\n";
if (bit( iflag, (4*1024))) print "seflg_xyz\n";
if (bit( iflag, (8*1024))) print "seflg_radians\n";
if (bit( iflag, (16*1024))) print "seflg_baryctr\n";
if (bit( iflag, (32*1024))) print "seflg_topoctr\n";
if (bit( iflag, (64*1024))) print "seflg_sidereal\n";
if (bit( iflag, (128*1024))) print "seflg_icrs\n";
if (bit( iflag, (256*1024))) print "seflg_new_mode\n";

quit
Und hier eine Beispielsitzung:
ruediger@herschel:~/workspace/swepar/src$ iflag 
iflag = 16912
seflg_truepos
seflg_nogdefl
seflg_baryctr

Nachtrag

Gegen eine Scriptsprache, die sich gewaschen hat, wie z.B. Perl, kann bc natürlich nicht ankommen. Das ist auch gar nicht die Absicht. bc will nicht viel mehr als eine Art fortgeschrittener Taschenrechner sein, der in die Unix-Philosophie integriert ist, d.h. sich komfortabel mit anderen Befehlen in der Kommandozeile kombinieren lässt.

Hier das selbe Beispiel in Perl:

#!/usr/bin/perl

my @SEFLG=qw(SEFLG_JPLEPH  SEFLG_SWIEPH    SEFLG_MOSEPH 
             SEFLG_HELCTR  SEFLG_TRUEPOS   SEFLG_J2000   
             SEFLG_NONUT   SEFLG_SPEED3    SEFLG_SPEED   
             SEFLG_NOGDEFL SEFLG_NOABERR   SEFLG_EQUATORIAL 
             SEFLG_XYZ     SEFLG_RADIANS   SEFLG_BARYCTR 
             SEFLG_TOPOCTR SEFLG_SIDEREAL  SEFLG_ICRS   
             SEFLG_NEW_MODE);
my $iflag = $ARGV[0];
foreach my $flag (@SEFLG) {
  print "$flag\n" if $iflag % 2;
  last unless $iflag >>= 1;
  }

Keine Kommentare:

Kommentar veröffentlichen