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

Advertisement


Random Article You May Like