Working With Number – Infinity Multiplication – Chapter 3B – Perl

Thank you all my reader for following up on the “Infinity” subject. This chapter is the sub-release chapter of Chapter 3 – Optimised The Code for Perl in the Infinity subject. This is a very short chapter before I move onto chapter four of the subject. I will start releasing chapter four of the Infinity subject as early as Saturday this week or latest is by Sunday this week. The modification in the code is just to make the code operate a bit quicker and more flexible.

I modified the code to make the program more flexible in terms of to be able to change the amount of digit the program can work with at a time. For Perl compiler that can handle long integer, the maximum amount of digits the program can work with at a time are nine digits. For Perl compiler that only handles 32 bits integer, the maximum amount of digits the program can work with at a time are five digits.

I introduced the $pad0 variable into the code. The $pad0 hold the amount of zero that need to be added to a result value for each cycle of multiplication. This was explained in the previous chapter. I changed the $prepos variable name to $digitneg to make the code more understandable. I also changed the method of getting the value for the $remainder variable to be the exact same method as the method that gets the value for the $leftover variable.

After all the changes the same benchmark test for the previous version of infiX was applied to this version of infiX. For this version of infiX, the program took 6.232 seconds to computes the multiplication result 100,000 times for the same two strings of digits, each string contained 40 digits and both strings did not contain the decimal. The earlier production version for normal usage of infiX took 22.333 seconds to compute the result for the same test. With the decimal, this version of infiX took 6.733 seconds while the earlier version of infiX took 25.012 seconds to compute the result. This version of infiX-vr-2 was set to compute nine digits at a time.

I also updated the test code to make the program run more interactively and not just a boring blank screen while waiting for the result.

What took me so long to release this chapter although it was short? In the last couple days, I have been a bit busy. I just finished launching a brand new web directory for anyone who owns a blog or a website that contain a good amount of articles can submit their website to be inclusive in the directory. If you have a blog, please feel free to submit your website’s link at http://directory.iblog.website. Iblog.website‘s main site was also launched. I also launched a brand web shop to separate the e-commerce operation from the blog. The shop can be found at http://shop.iblog.website.

Previous Chapter: Optimised The CodeNext Chapter: Beyond Memory

This below is the updated test code to compare the result from this version to any previous infiX program. This test doesn’t need to be modify if put under package main. If the test code is placed in the same libZ package, the “libZ::” have to be remove for the code to operate properly.

my $m = 0;
my $um = 0;
for (my $id = 0; $id < 50000; $id++){
    my $a1 = int(rand(99999));
    my $a2 = int(rand(99999));
    my $a3 = int(rand(99999));
    my $a4 = int(rand(99999));
    my $a5 = int(rand(99999));
    my $ac1 = int(rand(99999));
    my $ac2 = int(rand(99999));
    my $ac3 = int(rand(99999));
    my $ac4 = int(rand(99999));
    my $ac5 = int(rand(99999));
    
    my $b1 = int(rand(99999));
    my $b2 = int(rand(99999));
    my $b3 = int(rand(99999));
    my $b4 = int(rand(99999));
    my $b5 = int(rand(99999));
    my $bc1 = int(rand(99999));
    my $bc2 = int(rand(99999));
    my $bc3 = int(rand(99999));
    my $bc4 = int(rand(99999));
    my $bc5 = int(rand(99999));
    my $padA1 = "";
    my $padA2 = "";
    my $padB1 = "";
    my $padB2 = "";
    my $idn = 0;
    my $idn2 = 0;
   	while ( $idn < int(rand(15)) ){
    	$padA1 = "0" . $padA1;
        $idn++;
    }
    while ( $idn < int(rand(15)) + 15 ){
    	$padA2 = "0" . $padA2;
        $idn++;
    }
    while ( $idn2 < int(rand(15)) ){
    	$padB1 = "0" . $padB1;
        $idn2++;
    }
    while ( $idn2 < int(rand(15)) + 15 ){
    	$padB2 = "0" . $padB2;
        $idn2++;
    }
    
    my $ta = "+" . $a1 . $a2 . $a3 . $a4 . $a5 . "." . $padA1 . $ac1 . $ac2 . $ac3 . $padA2 . $ac4 . $ac5;  
    my $tb = "-" . $b1 . $b2 . $b3 . $b4 . $b5 . "." . $padB1 . $bc1 . $bc2 . $bc3 . $padB2 . $bc4 . $bc5;
    
    my $test1 = libZ::infiX($ta, $tb);
    my $test2 = libZ::infiX2($ta, $tb); 
    print "Cases #$id: $ta * $tb ";
    if ($test1 ne $test2){
    	$um = $um + 1;
    	print ("Unmatch Case #$um \n");
        print ("Question" .  " : " . $ta . " * " . $tb . "\n");
        print ("Version 3: " . $test1 . " Version 2: " . $test2 . "\n");
    }
    if ($test1 eq $test2){
    	$m = $m +1;
    }
    print "\n";
}

print "Matched $m case(s).\n";
print "Unmatched $um case(s).";

This is the infiX version vr 2 that was written for Perl.

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);

Digiprove sealCopyright secured by Digiprove © 2017

This post was written by Kevin and was first post @ http://kevinhng86.iblog.website.
Original Post Name: "Working With Number – Infinity Multiplication – Chapter 3B – Perl".
Original Post Link: http://kevinhng86.iblog.website/2017/03/02/working-with-number-infinity-multiplication-chapter-3b-perl/.

Advertisement


Random Article You May Like

Leave a Reply

Your email address will not be published. Required fields are marked *

*
*