mollusk 0e4acfb8f2 fix incorrect folder name for julia-0.6.x
Former-commit-id: ef2c7401e0876f22d2f7762d182cfbcd5a7d9c70
2018-06-11 03:28:36 -07:00

253 lines
8.2 KiB
Julia

# This file is a part of Julia, but is derived from
# https://github.com/google/double-conversion which has the following license
#
# Copyright 2006-2014, the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
const kDoubleSignificandSize = 53
function filldigits32fixedlength(n1,requested_len,buffer,len)
for i = (requested_len-1):-1:0
buffer[len+i] = 0x30 + n1 % 10
n1 = div(n1,10)
end
return len + requested_len
end
function filldigits32(n,buffer,len)
n_len = 0
while n != 0
digit = n % 10
n = div(n,10)
buffer[len+n_len] = 0x30 + digit
n_len += 1
end
i,j = len, len + n_len - 1
while i < j
buffer[i], buffer[j] = buffer[j], buffer[i]
i += 1
j -= 1
end
return len + n_len
end
function filldigits64fixedlength(n2,buffer,len)
kTen7 = 10000000
part2 = n2 % kTen7
n2 = div(n2,kTen7)
part0, part1 = divrem(n2,kTen7)
len = filldigits32fixedlength(part0, 3, buffer, len)
len = filldigits32fixedlength(part1, 7, buffer, len)
len = filldigits32fixedlength(part2, 7, buffer, len)
return len
end
function filldigits64(n3,buffer,len)
kTen7 = 10000000
part2 = n3 % kTen7
n3 = div(n3,kTen7)
part0, part1 = divrem(n3,kTen7)
if part0 != 0
len = filldigits32(part0, buffer, len)
len = filldigits32fixedlength(part1, 7, buffer, len)
len = filldigits32fixedlength(part2, 7, buffer, len)
elseif part1 != 0
len = filldigits32(part1, buffer, len)
len = filldigits32fixedlength(part2, 7, buffer, len)
else
len = filldigits32(part2, buffer, len)
end
return len
end
function roundup(buffer, len, decimal_point)
if len == 1
buffer[1] = 0x31
decimal_point = 1
len = 2
return len, decimal_point
end
buffer[len - 1] += 1
for i = (len-1):-1:2
buffer[i] != 0x30 + 10 && return len, decimal_point
buffer[i] = 0x30
buffer[i - 1] += 1
end
if buffer[1] == 0x30 + 10
buffer[1] = 0x31
decimal_point += 1
end
return len, decimal_point
end
function fillfractionals(fractionals, exponent,
fractional_count, buffer,
len, decimal_point)
if -exponent <= 64
point = -exponent
for i = 1:fractional_count
fractionals == 0 && break
fractionals *= 5
point -= 1
digit = fractionals >> point
buffer[len] = 0x30 + digit
len += 1
fractionals -= UInt64(digit) << point
end
if ((fractionals >> (point - 1)) & 1) == 1
len, decimal_point = roundup(buffer, len, decimal_point)
end
else
fract128 = UInt128(fractionals) << 64
fract128 = shift(fract128,-exponent - 64)
point = 128
for i = 1:fractional_count
fract128 == 0 && break
fract128 *= 5
point -= 1
digit, fract128 = divrem2(fract128,point)
buffer[len] = 0x30 + digit
len += 1
end
if bitat(fract128,point - 1) == 1
len, decimal_point = roundup(buffer, len, decimal_point)
end
end
return len, decimal_point
end
low(x) = UInt64(x&0xffffffffffffffff)
high(x) = UInt64(x >>> 64)
bitat(x::UInt128,y) = y >= 64 ? (Int32(high(x) >> (y-64)) & 1) : (Int32(low(x) >> y) & 1)
function divrem2(x,power)
h = high(x)
l = low(x)
if power >= 64
result = Int32(h >> (power - 64))
h -= UInt64(result) << (power - 64)
return result, (UInt128(h) << 64) + l
else
part_low::UInt64 = l >> power
part_high::UInt64 = h << (64 - power)
result = Int32(part_low + part_high)
return result, UInt128(l - (part_low << power))
end
end
function shift(x::UInt128,amt)
if amt == 0
return x
elseif amt == -64
return x << 64
elseif amt == 64
return x >> 64
elseif amt <= 0
h = high(x); l = low(x)
h <<= -amt
h += l >> (64 + amt)
l <<= -amt
return (UInt128(h) << 64) + l
else
h = high(x); l = low(x)
l >>= amt
l += h << (64 - amt)
h >>= amt
return (UInt128(h) << 64) + l
end
end
function trimzeros(buffer, len, decimal_point)
while len > 1 && buffer[len - 1] == 0x30
len -= 1
end
first_non_zero::Int32 = 1
while first_non_zero < len && buffer[first_non_zero] == 0x30
first_non_zero += 1
end
if first_non_zero != 1
for i = first_non_zero:(len-1)
buffer[i - first_non_zero + 1] = buffer[i]
end
len -= first_non_zero-1
decimal_point -= first_non_zero-1
end
return len, decimal_point
end
function fastfixedtoa(v,mode,fractional_count,buffer)
v = Float64(v)
significand::UInt64 = _significand(v)
exponent = _exponent(v)
exponent > 20 && return false, 0, 0
fractional_count > 20 && return false, 0, 0
len = 1
if exponent + kDoubleSignificandSize > 64
kFive17 = divisor = Int64(5)^17
divisor_power = 17
dividend = significand
if exponent > divisor_power
dividend <<= exponent - divisor_power
quotient = div(dividend,divisor)
remainder = (dividend % divisor) << divisor_power
else
divisor <<= divisor_power - exponent
quotient = div(dividend,divisor)
remainder = (dividend % divisor) << exponent
end
len = filldigits32(quotient, buffer, len)
len = filldigits64fixedlength(remainder, buffer, len)
decimal_point = len-1
elseif exponent >= 0
significand <<= exponent
len = filldigits64(significand, buffer, len)
decimal_point = len-1
elseif exponent > -kDoubleSignificandSize
integrals = significand >> -exponent
fractionals = significand - (integrals << -exponent)
if integrals > 0xFFFFFFFF
len = filldigits64(integrals,buffer,len)
else
len = filldigits32(integrals%UInt32,buffer,len)
end
decimal_point = len-1
len, decimal_point = fillfractionals(fractionals,exponent,fractional_count,
buffer,len, decimal_point)
elseif exponent < -128
len = 1
decimal_point = -fractional_count
else
decimal_point = 0
len, decimal_point = fillfractionals(significand,exponent,fractional_count,
buffer,len, decimal_point)
end
len, decimal_point = trimzeros(buffer,len,decimal_point)
buffer[len] = 0
if (len-1) == 0
decimal_point = -fractional_count
end
return true, len, decimal_point
end