Jump To …

Addr64.coffee

This class and two external methods provide container for long addresses - from 0 to 2^64-1. It is necessary because of JavaScript limitations for int.

class Addr64

@private

  left: undefined

@private

  right: undefined

@private

  limit: undefined

Constructor.

@param left left part of the number (adds left * 2^32 to the whole address). @param right right part of the number.

  @create$int$int: (left, right, o) ->
    if !o? then o = new Addr64
    o.left = left
    o.right = right
    o.limit = Math.pow 2, 32
    return o

Makes a copy of this object.

@return similar Addr64 object

  copy: () ->
    return Addr64.create$int$int @left, @right

Adds number to this Addr64.

@param num number to add. @return new address.

  plus$int: (num) ->
    newNum = num + @right
    left = @left
    right = 0
    if newNum < 0
      k = Math.floor(newNum / @limit)
      right = newNum - k * @limit
      left += k
    else if newNum < @limit
      right = newNum
    else
      right = newNum % @limit
      left += Math.floor(newNum / @limit)
    return Addr64.create$int$int left, right

Operation &.

@param mask another Addr64 object. @return new address.

  logAnd$Addr64: (mask) ->
    left = @left & mask.left
    right = @right & mask.right
    return Addr64.create$int$int left, right

Converts this Addr64 to float (for test purposes only).

@return number.

  toFloat: () ->
    return @left * @limit + @right

Calculates difference between this Addr64 and the second one.

@param second Addr64. @result the number that is equal to this - second.

  diff$Addr64: (second) ->
    return (@left - second.left) * @limit + @right - second.right

Equality comparison.

@param addr another Addr64 object. @return true or false.

  equals$Addr64: (addr) ->
    return @left == addr.left && @right == addr.right

Less comparison

@param addr another Addr64 object. @return true or false.

  less$Addr64: (addr) ->
    return (@left == addr.left && @right < addr.right) || @left < addr.left

Create null Address, i.e. equal to 2^64 - 1.

@return null Address

  @nullAddress: () ->
    return Addr64.create$int$int @limit - 1, @limit - 1

Converts Addr64 to string.

@param number Addr64 object to convert. @param base the base of convertion. @return string of length of 2^64 is this base. If necessary the string is filled up by zeroes in the beginning.

  @addr64ToString$Addr64$int: (number, base) ->
    len = Math.ceil(64 * (Math.log 2) / Math.log base)
    maxInt = Math.pow 2, 32
    strTemp = ""
    str = ""
    left = number.left
    right = number.right
    while (left != 0)
      rbase = (left % base) * maxInt + right
      left = Math.floor(left / base) +
      Math.floor(Math.floor(rbase / base) / maxInt)
      right = Math.floor(rbase / base) % maxInt
      digit = rbase % base
      strTemp = digit.toString(base).concat strTemp
    if (right != 0)
      strTemp = right.toString(base).concat strTemp
    for i in [0..len - strTemp.length - 1]
      str = str.concat "0"
    str = str.concat strTemp
    return str

Convert string to Addr64.

@param str string, must be not shorter than the length of 2^64 is this base. If string is longer then all the other symbols are ignored. @param base the base of convertion. @return Addr64 object.

  @stringToAddr64$String$int: (str, base) ->
    len = Math.ceil(64 * (Math.log 2) / Math.log base)
    maxInt = Math.pow 2, 32
    left = 0
    right = 0
    for i in [0..len - 1]
      digit = str.substr i, 1
      rbase = right * base + parseInt digit, base
      if rbase < maxInt
        right = rbase
      else
        right = rbase % maxInt
        left = left + Math.floor(rbase / maxInt)
    return Addr64.create$int$int left, right

  toString: () ->
    return Addr64.addr64ToString$Addr64$int this, 16

exports.Addr64 = Addr64