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