Perl Function – Infinity Multiplication – Version vr-2 – Normal Usage Production Version

Advertisement

# "Copyright Notice", please do not remove.
# Written by Kevin Ng
# The full tutorial on this subject can be found @ http://kevinhng86.iblog.website or http://programming.world.edu.
# Release date to http://programming.world.edu will lag one week after release on http://kevinhng86.iblog.website 
# This source code file is a part of Kevin Ng's Z library.
# This source code is licenses under CCDL-1.0  A copy of CDDL1.0 can be found at https://opensource.org/licenses/CDDL-1.0
# End "Copyright Notice" 

# Notice: Version: InfiX-vr-2 (Infinity Multiplication) | Normal Usage | Bound by some limitation.  
#         The first limitation of this version is how much memory Perl allow the string to be store.
#         The second limitation is how much memory Perl can assign to the program.
#         If memory allow, for this version a string can only be less than 1,073,741,823 digits
#
#    Example of memory usage calculation:
#         500 megabyte string of digits multiply to another 500 megabyte string of digits.
#         1000 Mb of memory to store the strings outside of the function.
#         1000 Mb of memory for when the strings are passing into the function. 
#         1000 Mb for the answer string.
#          100 Mb (this can vary but most likely to be less than this) for script operation.
#         3100 Mb of memory is requires for adding two strings of digits that costed 500MB per string.
#
# Noticeable Feature: You can change the $digit variable to the amount of digits you want to work with at a time.
#                     The maximum amount of digits you can work with at a time if your Perl compiler support long integer is nine.
#                     If your Perl compiler does not support long integer and only support 32 bits integer, the maximu of digit you can with is five digits at a time.

use strict;

package libZ;

    sub infiX{     
        my ($a, $b) = @_;
        my $isaNeg = substr($a,0,1) eq "-";
        my $isbNeg = substr($b,0,1) eq "-";       
        $a =~  s/^[+-]+//g ;
        $b =~ s/^[+-]+//g;    
        $a =~ s/^0+//g;
        $b =~  s/^0+//g; 
        
        my $aDecPos = index($a, ".");
        my $bDecPos = index($b, ".");
        my $oDecPos = 0;
        
        if ( $aDecPos > -1 ){
            $a =~ s/0+$//g ;
            $aDecPos = ( length($a) - 1 - $aDecPos) > 0? ( length($a) - 1 - $aDecPos) : 0;
            $a =~ s/[.]//g ; 
        }
        if ( $bDecPos > -1 ){    
            $b =~ s/0+$//g ;
            $bDecPos = ( length($b) - 1 - $bDecPos) > 0? (length($b) - 1 - $bDecPos) : 0;
            $b =~ s/[.]//g ;
        }
        
        
        if ( (length($a) < 1 || length($b) < 1 ) ){
            return "0";    
        }
        
        if ( $a eq "1" && $aDecPos < 1 ){
            if ( $bDecPos > 0 ){
                $b = substr($b, 0, length($b) - $bDecPos) . "." . substr($b, length($b) - $bDecPos); 
                $b = substr($b, 0, 1) eq "."? "0" . $b : $b;
                return (($isaNeg ne $isbNeg)? "-" . $b : $b);
            }
            return (($isaNeg ne $isbNeg)? "-" . $b : $b);
        }

        if ( $b == "1" && $bDecPos < 1 ){
            if ( $aDecPos > 0 ){
                $a = substr($a, 0, length($a) - $aDecPos) . "." . substr($a, length($a) - $aDecPos); 
                $a = substr($a,0,1) eq "."? "0" . $a: $a;
                return (($isaNeg ne $isbNeg)? "-" . $a : $a);
            }
            return (($isaNeg ne $isbNeg)? "-" . $a : $a);
        }
        
        if ( $aDecPos > -1 || $bDecPos > -1 ){
            $aDecPos = $aDecPos > -1? $aDecPos : 0;
            $bDecPos = $bDecPos > -1? $bDecPos : 0;        
            $oDecPos = $aDecPos + $bDecPos;
        }
        
        my $temp = 0;
        my $alen = length($a);
        my $blen = length($b);
        my $output = "";
        my $bi = $blen;
        my $posr = 0;
        my $posw = 0;
        my $digit = 9;
        my $digitneg = $digit * -1;
        my $pad0 = "";
        while ( length($pad0) < $digit - 1 ){
            $pad0 = "0" . $pad0 ;
        }

        while ( $bi > 0 ){
            my $z = int(substr($b, ($bi - $digit > -1? $bi - $digit : 0), ($bi - 0 < $digit? $bi - 0: $digit)));
            my $outlen = length($output);
            my $ai = $alen;
            my $leftover = 0;

            if ( $outlen < 1 ){        
                while ( $ai > 0){
                    $temp = int(substr($a, ($ai - $digit > -1? $ai - $digit : 0), ($ai - 0 < $digit? $ai - 0: $digit))) * $z + $leftover;
                    $leftover = int(substr($temp,0, $digitneg) || 0 ) ;
                    $output = substr($pad0 . substr($temp, $digitneg), $digitneg) . $output;
                    $ai = $ai - $digit;
                }
                $output = $leftover > 0? substr($pad0 . substr($leftover, $digitneg), $digitneg) . $output : $output;
            } else {
                my $remainder = 0;
                my $tempadd = 0;
                my $loopidx = 0;
                while ( $ai > 0){
                    $posw = ($posr + $loopidx) * $digitneg;
                    $temp = int(substr($a, ($ai - $digit > -1? $ai - $digit : 0), ($ai - 0 < $digit? $ai - 0: $digit))) * $z + $leftover + $remainder;
                    $leftover = int(substr($temp,0, $digitneg) || 0 ) ;
                    $tempadd = int(substr($temp,$digitneg)) + int(substr($output,$posw + $digitneg,$posw) || 0) ;   
                    $remainder =  int(substr($tempadd,0, $digitneg) || 0 );
                    $output = substr($output,0, $posw + $digitneg) . substr($pad0 . substr($tempadd,$digitneg), $digitneg) . substr($output,$posw);
                    $loopidx = $loopidx + 1;
                    $ai = $ai - $digit;
                }
                $output = ($remainder + $leftover > 0)? substr($pad0 . ($remainder + $leftover), $digitneg) . $output: $output;
            }
            $posr = $posr + 1;
            $bi = $bi - $digit;
        }

        
        if ( $oDecPos > 0 ){
            while (length($output) < $oDecPos){
                $output = "0" . $output;
            }
            $output = substr($output, 0 , length($output) - $oDecPos) . "." . substr($output, length($output) - $oDecPos);
            $output =~ s/0+$//g;
            $output =~ s/^0+//g;
            $output =~ s/[.]$//g;
            $output = substr($output, 0, 1) eq "."? "0" . $output : $output;
            return ($isaNeg ne $isbNeg? "-" . $output : $output);
        }       
        $output =~ s/^0+//g;
        return ($isaNeg ne $isbNeg? "-" . $output : $output);
    }


package main;
my $x = "-1234567890123456789012354678901234567890";
my $y = "+1234567890123456789012345678901234567890";
print libZ::infiX($x,$y);
Advertisement


Random Article You May Like