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

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 Ruby 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. The _digit variable can be modified to adapt the program to work with how many digits at a time bases on the environment the program is working with. I set the infiX program to work with nine digits at a time and also tested the program in the Ruby 2.3.1 environment.

What had been modified? I introduced the _pad0 variable into the code. The _pad0 variable holds 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.

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 10.798 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.300 seconds to compute the result for the same test. With the decimal, this version of infiX took 11.541 seconds while the earlier version of infiX took 24.158 seconds to compute the result. This version of infiX-vr-2 was set to compute nine digits at a time.

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 new 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. If you run this test code from the console, it will be more interactive and display more meaningful information while the test cases are executing.

um = 0
m = 0
for id in 0...50000
    a1 = rand(0...99999)
    a2 = rand(0...99999)
    a3 = rand(0...99999)
    a4 = rand(0...99999)
    a5 = rand(0...99999)
    ac1 = rand(0...99999)
    ac2 = rand(0...99999)
    ac3 = rand(0...99999)
    ac4 = rand(0...99999)
    ac5 = rand(0...99999)
    
    b1 = rand(0...99999)
    b2 = rand(0...99999)
    b3 = rand(0...99999)
    b4 = rand(0...99999)
    b5 = rand(0...99999)
    bc1 = rand(0...99999)
    bc2 = rand(0...99999)
    bc3 = rand(0...99999)
    bc4 = rand(0...99999)
    bc5 = rand(0...99999)
    padA1 = ""
    padA2 = ""
    padB1 = ""
    padB2 = ""
    idn = 0
    idn2 = 0
   	while ( idn < rand(0...15) ) do
    	padA1 = "0" + padA1
      idn = idn + 1
    end
    while ( idn < rand(15...30) ) do
    	padA2 = "0" + padA2
      idn = idn + 1
    end
    while ( idn2 < rand(0...15) ) do
    	padB1 = "0" + padB1
      idn2 = idn2 + 1 
    end
    while ( idn2 < rand(15...30) ) do
    	padB2 = "0" + padB2
      idn2 = idn2 + 1
    end
    
    ta = "+" + a1.to_s + a2.to_s + a3.to_s + a4.to_s + a5.to_s + "." + padA1 + ac1.to_s + ac2.to_s + ac3.to_s + padA2 + ac4.to_s + ac5.to_s;  
    tb = "-" + b1.to_s + b2.to_s + b3.to_s + b4.to_s + b5.to_s + "." + padB1 + bc1.to_s + bc2.to_s + bc3.to_s + padB2 + bc4.to_s + bc5.to_s;
    
    test1 = LibZ.infiX(ta, tb)
    test2 = LibZ.infiX2(ta, tb) 
    puts "Cases ##{id}: #{ta} * #{tb}"
    if (test1 != test2)
        um = um + 1
        puts ("Unmatched : ##{ um }")
        puts ("Question" +  " : " + ta + " * " + tb )
        puts ("Version 3: " + test1 )
        puts ("Version 2: " + test2 )
    end
    if (test1 == test2)
        m = m + 1
    end
    puts        
end
puts "Matched ##{m}"
puts "Unmatched ##{um}"

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

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 Ruby allow the string to be store.
#         The second limitation is how much memory Ruby 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 digit you want to work with at a time.
#                     Ruby native multiplication does support very large number, just not precisely calculating the decimal.
#                     Nevertheless in the event where you have to work in a more restricted version of Ruby, you can change the _digit variable to a lesser amount.

class LibZ
    def self.infiX(_a,_b)
    
        _isaNeg = _a[0] == "-"
        _isbNeg = _b[0] == "-"       
        _a = _a.gsub(/^[+-]/,"")
        _b = _b.gsub(/^[+-]+/,"")    
        _a = _a.gsub(/^0+/, "")
        _b = _b.gsub(/^0+/, "") 
        
        _aDecPos = _a.index(".") || -1
        _bDecPos = _b.index(".") || -1
        _oDecPos = 0
        
        if ( _aDecPos > -1 )
            _a = _a.gsub(/0+$/, "")
            _aDecPos = (_a.length - 1 - _aDecPos) > 0? (_a.length - 1 - _aDecPos) : 0
            _a = _a.gsub(/[.]/, "")
        end
    
        if ( _bDecPos > -1)    
            _b = _b.gsub(/0+$/, "")
            _bDecPos = (_b.length - 1 - _bDecPos) > 0? (_b.length - 1 - _bDecPos) : 0
            _b = _b.gsub(/[.]/, "")
        end
        
        if ( _a.length < 1 or _b.length < 1  )
            return "0"    
        end

        if ( _a == "1" && _aDecPos < 1 )
            if ( _bDecPos > 0 )
                _b = _b[0...(_b.length - _bDecPos )] + "." + _b[(_b.length - _bDecPos)..._b.length]
                _b = _b[0] == "."? "0" + _b: _b
                return ((_isaNeg != _isbNeg)? "-" + _b : _b)
            end
            return ((_isaNeg != _isbNeg)? "-" + _b : _b)
        end
        
        if ( _b == "1" && _bDecPos < 1 )
            if ( _aDecPos > 0 )
                _a = _a[0...(_a.length - _aDecPos )] + "." + _a[(_a.length - _aDecPos)..._a.length]
                _a = _a[0] == "."? "0" + _a: _a
                return ((_isaNeg != _isbNeg)? "-" + _a : _a)
            end
            return ((_isaNeg != _isbNeg)? "-" + _a : _a)
        end
        
        if ( _aDecPos > -1 || _bDecPos > -1  )
            _aDecPos = (_aDecPos > -1)? _aDecPos : 0
            _bDecPos = (_bDecPos > -1)? _bDecPos : 0        
            _oDecPos = _aDecPos + _bDecPos
        end
        
        _temp = 0
        _alen = _a.length
        _blen = _b.length
        _output = ""
        _bi = _blen
        _posr = 0
        _posw = 0
        _digit = 9
        _digitneg = _digit * -1
        _pad0 = ""
        
        while (_pad0.length < _digit - 1) do
          _pad0 = "0" + _pad0
          
        end
        
    
        while ( _bi > 0 ) do
            _z = _b[(_bi - _digit > -1? _bi - _digit : 0)...((_bi - 0 < _digit)? _bi - 0: _bi)].to_i
            _outlen = _output.length
            _ai = _alen
            _leftover = 0
            
            if ( _outlen < 1 )        
                while ( _ai > 0) do
                _temp = (_a[(_ai - _digit > -1? _ai - _digit : 0)...((_ai - 0 < _digit)? _ai - 0: _ai)].to_i * _z + _leftover).to_s
                _leftover = _temp[0..._digitneg].to_i
                _temp = _pad0 + _temp
                _output = _temp[_digitneg..-1] + _output
                _ai = _ai - _digit
                end
                if ( _leftover > 0 )
                    _output = (_pad0 + _leftover.to_s)[_digitneg..-1] + _output 
                end
            else 
                _remainder = 0
                _tempadd = 0
                _loopidx = 0
                while ( _ai > 0) do
                    _posw = (_posr + _loopidx) * _digitneg;
                    _temp = (_a[(_ai - _digit > -1? _ai - _digit : 0)...((_ai - 0 < _digit)? _ai - 0: _ai)].to_i * _z + _leftover + _remainder).to_s
                    _leftover = _temp[0..._digitneg].to_i
                    _tempadd = ( (_temp[_digitneg..-1] || _temp[0..-1]).to_i + _output[(_posw + _digitneg)..._posw].to_i).to_s   
                    _remainder = _tempadd[0..._digitneg].to_i
                    _tempadd = _pad0 + (_tempadd[_digitneg..-1] || _tempadd[0..-1] ) 
                    _output = _output[0...(_posw + _digitneg)] + _tempadd[_digitneg..-1] + (_output[_posw..-1] || _output[0..-1])
                    _loopidx = _loopidx + 1
                    _ai = _ai - _digit
                end
                if ( _remainder + _leftover > 0 )
                    _output = (_pad0 + (_leftover + _remainder).to_s)[_digitneg..-1] + _output 
                end
            end
            _posr = _posr + 1
            _bi = _bi - _digit
        end
    
        if ( _oDecPos > 0 )
            while (_output.length < _oDecPos) do
                _output = "0" + _output
            end
            _output = _output[0...(_output.length - _oDecPos)] + "." + _output[(_output.length - _oDecPos)..._output.length]
            _output = _output.gsub(/0+$/,"")
            _output = _output.gsub(/[.]$/, "")
            _output = _output.gsub(/^0+/, "")
            _output = _output[0] == "."? "0" + _output : _output
            return ((_isaNeg != _isbNeg)? "-" + _output : _output)
        end
        _output = _output.gsub(/^0+/, "")
        return ((_isaNeg != _isbNeg)? "-" + _output : _output)
    end
    
end

x = "1234567890123456789012345678901234567890"
y = "1234567890123456789012345678901234567890"

puts 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 – Ruby".
Original Post Link: http://kevinhng86.iblog.website/2017/03/03/working-with-number-infinity-multiplication-chapter-3b-ruby/.

Advertisement


Random Article You May Like

One thought on “Working With Number – Infinity Multiplication – Chapter 3B – Ruby

  1. Hey I am so delighted I found your weblog, I really found you by error, while I was searching on Yahoo for something else, Regardless I am here now and would just like to say many thanks for a fantastic post and a all round interesting blog (I also love the theme/design), I don’t have time to browse it all at the minute but I have saved it and also added in your RSS feeds, so when I have time I will be back to read a great deal more, Please do keep up the awesome b.|

Leave a Reply

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

*
*