text: May
  4
  A Non-Scientific Comparison of Java and Perl
  Filed Under Computers & Tech, Software Development on May 4, 2007 at 2:36 pm]
  The Algorithm
  The algorithm was very simple and doubtless not ‘best practice’. Because my binary operator knowledge is very rusty I converted from HEX to binary using a lookup table (only took a minute or so to throw together a quick hash indexed by the 16 hex characters that contained the 16 equivalent binary strings). So, in one quick
  foreach loop the program converted the hex to a binary string, then the binary string was reversed, and finally looped through multiplying each binary digit by two to the power of its position in the string and all those results summed together for an answer. This is a very simple algorithm that’s easy to implement and that works. Remember, the aim in hacking a solution is to get an answer as quick as possible, not to write a great program!
  Before we go any further lets have a look at the code.
  The Perl Implementation
  [perl]
  #!/usr/bin/perl
  use strict;
  my $hex = $ARGV[0];
  $hex =~ s/\-//g;
  my $bin = ”;
  my $hexToBin = {
  0 => ‘0000’,
  1 => ‘0001’,
  2 => ‘0010’,
  3 => ‘0011’,
  4 => ‘0100’,
  5 => ‘0101’,
  6 => ‘0110’,
  7 => ‘0111’,
  8 => ‘1000’,
  9 => ‘1001’,
  A => ‘1010’,
  B => ‘1011’,
  C => ‘1100’,
  D => ‘1101’,
  E => ‘1110’,
  F => ‘1111’,
  };
  foreach my $i (0..length($hex)){
  $bin .= $hexToBin->{substr($hex, $i, 1)}
  }
  print “Binary: $bin\n”;
  my $binRev = reverse($bin);
  my $ans = 0;
  foreach my $i (0..length($binRev)){
  $ans += substr($binRev, $i, 1) * 2**$i;
  }
  print “Decimal: $ans\n”;
  [/perl]
  The Java Implementation
  [java]
  import java.math.BigInteger;
  public class hex2dec {
  public static void main(String args[]) {
  String hex = args[0].replaceAll(“-“, “”);
  String bin = hex2bin(hex);
  System.out.println(“Binary: ” + bin);
  BigInteger ans = bin2dec(bin);
  System.out.println(“Decimal: ” + ans.toString());
  }
  public static String hexCharToBinString(char h) {
  switch (h) {
  case ‘0’:
  return “0000”;
  case ‘1’:
  return “0001”;
  case ‘2’:
  return “0010”;
  case ‘3’:
  return “0011”;
  case ‘4’:
  return “0100”;
  case ‘5’:
  return “0101”;
  case ‘6’:
  return “0110”;
  case ‘7’:
  return “0111”;
  case ‘8’:
  return “1000”;
  case ‘9’:
  return “1001”;
  case ‘A’:
  return “1010”;
  case ‘B’:
  return “1011”;
  case ‘C’:
  return “1100”;
  case ‘D’:
  return “1101”;
  case ‘E’:
  return “1110”;
  case ‘F’:
  return “1111”;
  }
  return “”;
  }
  public static String hex2bin(final String hex) {
  StringBuffer ans = new StringBuffer();
  for(int i = 0; i < hex.length(); i++) { ans.append(hexCharToBinString(hex.charAt(i))); } return ans.toString(); } public static BigInteger bin2dec(final String b) { BigInteger ans = new BigInteger("0"); String binRev = ((new StringBuffer(b)).reverse()).toString(); for(int i = 0; i < binRev.length(); i++) { ans = ans.add(binCharToBigInt(binRev.charAt(i)).multiply(twoToThePowerOf(i))); } return ans; } public static BigInteger binCharToBigInt(char b) { if(b == '1') { return new BigInteger("1"); } return new BigInteger("0"); } public static BigInteger twoToThePowerOf(int n) { if(n == 0) { return new BigInteger("1"); } if(n == 1) { return new BigInteger("2"); } BigInteger ans = new BigInteger("2"); for(int i = 1; i < n; i++) { //ans *= 2; ans = ans.multiply(new BigInteger("2")); } return ans; } } [/java]
  Some Points I Noted
  As the title suggests, this is not even a remotely scientific comparison. But I do just want to point out some things that struck me while implementing the same algorithm in the two languages one after the other.
  - Size – Well, if you’re surprised that the Perl implementation is a lot shorter you probably don’t know very much about Perl 🙂 However, in this case the solution in Java is well over twice as long (38 lines v 88 lines).
  - Data Structures – It’s far easier to create a simple hash in Perl. I Java you have to jump through too many hoops with boxing and un-boxing so I didn’t even bother and just used a function with a switch statement.
  - Loops – I find the Perl
  foreachloops a lot simpler to understand at a glance.
  - Operators – It’s easier to see what’s going on in the Perl loops thanks to the range operator (
  ..). Raising two to the power of
  iis also easier in Perl because of the
  **operator. Java is missing both these operators. Java does have power functions via the
  java.lang.Mathbut this function uses floating point arithmetic and hence is no good for integer maths. So, I had to implement my own function for raising two to the appropriate power.
  - String Manipulation – The Java
  Stringclass is missing some pretty basic functionality, including a function for reversing it. In Perl this is trivial, there is a built in reverse function! In Java I had to temporarily convert my
  Stringto a
  StringBufferto reverse it. This is responsible for the following very ugly line of code:
  String binRev = ((new StringBuffer(b)).reverse()).toString();
  If you only wanted to convert the number from hexadecimal to decimal, you could have used Ruby:
  irb(main):001:0> “09F911029D74E35BD84156C5635688C0”.hex
  => 13256278887989457651018865901401704640
  Of course, writing your own algorithms is a lot more fun! 🙂
  Well … since I don’t know ruby it would have taken me quite a while to do it that way 😉
  perl has a hex function and BigNumber support, too. 🙂
  % perl -Mbignum -wle’print hex pop’ 09F911029D74E35BD84156C5635688C0
  13256278887989457651018865901401704640