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