       1 package ConversionsUtil;
       2 #
       3 # $RCSfile: ConversionsUtil.pm,v $
       4 # $Date: 2015/02/28 20:47:02 $
       5 # $Revision: 1.22 $
       6 #
       7 # Author: Manish Sud <msud@san.rr.com>
       8 #
       9 # Copyright (C) 2015 Manish Sud. All rights reserved.
      10 #
      11 # This file is part of MayaChemTools.
      12 #
      13 # MayaChemTools is free software; you can redistribute it and/or modify it under
      14 # the terms of the GNU Lesser General Public License as published by the Free
      15 # Software Foundation; either version 3 of the License, or (at your option) any
      16 # later version.
      17 #
      18 # MayaChemTools is distributed in the hope that it will be useful, but without
      19 # any warranty; without even the implied warranty of merchantability of fitness
      20 # for a particular purpose.  See the GNU Lesser General Public License for more
      21 # details.
      22 #
      23 # You should have received a copy of the GNU Lesser General Public License
      24 # along with MayaChemTools; if not, see <http://www.gnu.org/licenses/> or
      25 # write to the Free Software Foundation Inc., 59 Temple Place, Suite 330,
      26 # Boston, MA, 02111-1307, USA.
      27 #
      28
      29 use strict;
      30 use Exporter;
      31 use Constants;
      32
      33 use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
      34
      35 @ISA = qw(Exporter);
      36
      37 # Groups of conversion functions...
      38 my(@MathConversions) = qw(DegreesToRadians RadiansToDegrees);
      39 my(@NumericBaseConversions) = qw(BinaryToDecimal DecimalToBinary HexadecimalToDecimal DecimalToHexadecimal OctalToDecimal DecimalToOctal BinaryToHexadecimal HexadecimalToBinary HexadecimalToOctal OctalToHexadecimal StringToBinary StringToHexadecimal);
      40
      41 # Export all conversion functions...
      42 @EXPORT = (@MathConversions, @NumericBaseConversions);
      43 @EXPORT_OK = qw();
      44
      45 %EXPORT_TAGS = (
      46                 math => [@MathConversions],
      47                 all  => [@EXPORT, @EXPORT_OK]
      48                );
      49
      50
      51 # Degrees to radians...
      52 sub DegreesToRadians ($;$) {
      53   my($Degrees, $IgnoreWrap) = @_;
      54   my($Radians, $WrapValue);
      55
      56   $WrapValue = (defined($IgnoreWrap) && $IgnoreWrap) ? 0 : 1;
      57   if ($Degrees > 360 && $WrapValue) {
      58     $Degrees = $Degrees % 360;
      59   }
      60   $Radians = ($Degrees * TwoPi) / 360;
      61
      62   return $Radians;
      63 }
      64
      65 # Radians to degrees...
      66 sub RadiansToDegrees ($;$) {
      67   my($Radians, $IgnoreWrap) = @_;
      68   my($Degrees, $WrapValue);
      69
      70   $WrapValue = (defined($IgnoreWrap) && $IgnoreWrap) ? 0 : 1;
      71   $Degrees = ($Radians * 360) / TwoPi;
      72   if ($Degrees > 360 && $WrapValue) {
      73     $Degrees = $Degrees % 360;
      74   }
      75
      76   return $Degrees;
      77 }
      78
      79 # Convert a binary string to a decimal number...
      80 sub BinaryToDecimal ($) {
      81   my($Value) = @_;
      82
      83   if ($Value !~ /^0b/) {
      84     $Value = "0b${Value}";
      85   }
      86   return _ConvertToDecimal($Value);
      87 }
      88
      89 # Convert a decimal number into a binary string...
      90 sub DecimalToBinary ($) {
      91   my($Value) = @_;
      92
      93   return sprintf("%b", $Value);
      94 }
      95
      96 # Convert a hexadecimal string to a decimal number...
      97 sub HexadecimalToDecimal ($) {
      98   my($Value) = @_;
      99
     100   if ($Value !~ /^0x/) {
     101     $Value = "0x${Value}";
     102   }
     103   return _ConvertToDecimal($Value);
     104 }
     105
     106 # Convert a decimal number into a hexadecimal string...
     107 sub DecimalToHexadecimal ($) {
     108   my($Value) = @_;
     109
     110   return sprintf("%x", $Value);
     111 }
     112
     113 # Convert an octal string to a decimal number...
     114 sub OctalToDecimal ($) {
     115   my($Value) = @_;
     116
     117   if ($Value !~ /^0/) {
     118     $Value = "0${Value}";
     119   }
     120   return _ConvertToDecimal($Value);
     121 }
     122
     123 # Convert a decimal number into an octal string...
     124 sub DecimalToOctal ($) {
     125   my($Value) = @_;
     126
     127   return sprintf("%o", $Value);
     128 }
     129
     130 # Convert string into a binary string. Going from left to right, two ways of arranging bits
     131 # inside each byte are available: Most Significat Bits (MSB) first or Least Significat Bits (LSB)
     132 # first. Default is MSB corresponding to  descending bits order (PerlSpeak) inside each
     133 # each packed byte (Most singificat bits first).
     134 #
     135 sub StringToBinary ($;$) {
     136   my($Value, $UseReverseBitOrder) = @_;
     137   my($BinTemplate);
     138
     139   $BinTemplate = (defined($UseReverseBitOrder) && $UseReverseBitOrder) ? 'b*' : 'B*';
     140   return unpack($BinTemplate, $Value);
     141 }
     142
     143 # Convert string into a hexadecimal string. Two ways of arranging nybbles (pair of 4 bits in each
     144 # byte) are available: high nybbles first or low nybbles first. Default is MSB corresponding to high
     145 # nybbles (PerlSpeak) first. Low and high nybbles correspond to pair of a low and high four bits in a byte.
     146 #
     147 sub StringToHexadecimal ($;$) {
     148   my($Value, $UseReverseBitOrder) = @_;
     149   my($HexTemplate);
     150
     151   $HexTemplate = (defined($UseReverseBitOrder) && $UseReverseBitOrder) ? 'h*' : 'H*';
     152   return unpack($HexTemplate, $Value);
     153 }
     154
     155 # Convert a binary string into a hexadecimal string...
     156 #
     157 sub BinaryToHexadecimal ($;$) {
     158   my($Value, $UseReverseBitOrder) = @_;
     159   my($BinTemplate, $HexTemplate);
     160
     161   $BinTemplate = (defined($UseReverseBitOrder) && $UseReverseBitOrder) ? 'b*' : 'B*';
     162   $HexTemplate = (defined($UseReverseBitOrder) && $UseReverseBitOrder) ? 'h*' : 'H*';
     163
     164   return unpack($HexTemplate, pack($BinTemplate, $Value));
     165 }
     166
     167 # Convert a hexadecimal string into a binary string...
     168 #
     169 sub HexadecimalToBinary ($;$) {
     170   my($Value, $UseReverseBitOrder) = @_;
     171   my($BinTemplate, $HexTemplate);
     172
     173   $BinTemplate = (defined($UseReverseBitOrder) && $UseReverseBitOrder) ? 'b*' : 'B*';
     174   $HexTemplate = (defined($UseReverseBitOrder) && $UseReverseBitOrder) ? 'h*' : 'H*';
     175
     176   return unpack($BinTemplate, pack($HexTemplate, $Value));
     177 }
     178
     179 # Convert a hexadecimal string into a octal string...
     180 #
     181 sub HexadecimalToOctal {
     182   my($Hexadecimal) = @_;
     183
     184   return DecimalToOctal(HexadecimalToDecimal($Hexadecimal));
     185 }
     186
     187 # Convert a octal string into a hexadecimal string...
     188 #
     189 sub OctalToHexadecimal {
     190   my($Octal) = @_;
     191
     192   return DecimalToHexadecimal(OctalToDecimal($Octal));
     193 }
     194
     195 # Use Perl oct function to convert binary, octal or hexadecimal strings into decimal numbers.
     196 sub _ConvertToDecimal ($) {
     197   my($Value) = @_;
     198
     199   return ($Value =~ /^0/) ? oct($Value) : $Value;
     200 }
     201