Skip to content

Instantly share code, notes, and snippets.

@tav
Created September 7, 2012 16:36
Show Gist options
  • Select an option

  • Save tav/3667636 to your computer and use it in GitHub Desktop.

Select an option

Save tav/3667636 to your computer and use it in GitHub Desktop.
# Public Domain (-) 2012 The Ampify Authors.
# See the Ampify UNLICENSE file for details.
define 'amp', (exports, root) ->
WORD_SIZE = 30
DIGIT_BASE = 1 << WORD_SIZE
DIGIT_MASK = DIGIT_BASE - 1
HALF_WORD_SIZE = WORD_SIZE / 2
HALF_DIGIT_BASE = 1 << HALF_WORD_SIZE
HALF_DIGIT_MASK = HALF_DIGIT_BASE - 1
INTEGER_CACHE_SIZE = 100
LOG_BASE_10 = Math.log(10) / Math.LN2
ceil = Math.ceil
pow = Math.pow
integer = (v) ->
if not (this instanceof integer)
return new integer v
switch typeof v
when "string"
@c = 2
when "number"
if isNaN(v) or not isFinite v
throw new TypeError "not a valid number: `#{v}`"
if v <= DIGIT_MASK and v >= -DIGIT_MASK
v |= 0
if v >= 0
if cache and v <= INTEGER_CACHE_SIZE
return cache[v+INTEGER_CACHE_SIZE]
@p = true
else
if cache and v >= -INTEGER_CACHE_SIZE
return cache[v+INTEGER_CACHE_SIZE]
@p = false
v = -v
@d = new Int32Array @b = new ArrayBuffer(8), 0, @c = 1
@d[0] = v
else if v <= 9007199254740991 and v >= -9007199254740991
return new integer parseInt(v, 10).toString()
else
throw new RangeError 'cannot convert Numbers outside of the 53-bit range'
else
throw new TypeError "not a valid number: `#{v}`"
return
exports.integer = integer
integer::toString = ->
switch @c
when 1
if @p
return @d[0].toString()
return "-#{@d[0].toString()}"
when 0
return "0"
else
# Estimate the size of the final string.
l = @c - 1
l = ceil(((l * WORD_SIZE) + bitlen(@d[l]))/LOG_BASE_10)
s = []
return "size: #{l}"
cache = (new integer(i) for i in [-INTEGER_CACHE_SIZE..INTEGER_CACHE_SIZE])
cache[0].c = 0
exports.cache = cache
bitlen = (w) ->
n = 0
if w >= 32768
w >>= 16
n += 16
if w >= 128
w >>= 8
n += 8
if w >= 8
w >>= 4
n += 4
if w >= 2
w >>= 2
n += 2
if w >= 1
n++
return n
exports.foo = foo = new integer(12884901762)
foo.c = 2
foo.b = new ArrayBuffer(8)
foo.d = new Int32Array(foo.b, 0, 2)
foo.d[0] = 1073741698
foo.d[1] = 11
integer::toNumber = ->
v = @d[0]
`for (var i = 1; i < this.c; i++) {
v += this.d[i] * pow(DIGIT_MASK, i)
}`
return v
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment