Skip to content

Commit

Permalink
Make printing more Julian
Browse files Browse the repository at this point in the history
  • Loading branch information
quinnj committed Aug 7, 2019
1 parent d83435e commit cc5df43
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 129 deletions.
21 changes: 13 additions & 8 deletions base/ryu/Ryu.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,32 @@ shortestdigits(::Type{Float32}) = 39 + 9
shortestdigits(::Type{Float16}) = 9 + 5

function writeshortest(x::T) where {T <: Base.IEEEFloat}
buf, pos = writeshortest(x, Vector{UInt8}(undef, shortestdigits(T)), 1)
return String(buf[1:pos-1])
buf = Vector{UInt8}(undef, shortestdigits(T))
pos = writeshortest(x, buf, 1)
return unsafe_string(pointer(buf), pos-1)
end

function writefixed(x::T, precision) where {T <: Base.IEEEFloat}
buf, pos = writefixed(x, precision, Vector{UInt8}(undef, precision + shortestdigits(T)), 1)
return String(buf[1:pos-1])
buf = Vector{UInt8}(undef, precision + shortestdigits(T))
pos = writefixed(x, precision, buf, 1)
return unsafe_string(pointer(buf), pos-1)
end

function writeexp(x::T, precision) where {T <: Base.IEEEFloat}
buf, pos = writeexp(x, precision, Vector{UInt8}(undef, precision + shortestdigits(T)), 1)
return String(buf[1:pos-1])
buf = Vector{UInt8}(undef, precision + shortestdigits(T))
pos = writeexp(x, precision, buf, 1)
return unsafe_string(pointer(buf), pos-1)
end

function Base.show(io::IO, x::T) where {T <: Base.IEEEFloat}
if get(io, :compact, false)
precision = T == Float16 ? 5 : 6
buf, pos = writefixed(x, precision, Vector{UInt8}(undef, precision + shortestdigits(T)), 1)
buf = Vector{UInt8}(undef, precision + shortestdigits(T))
pos = writefixed(x, precision, buf, 1)
GC.@preserve buf unsafe_write(io, pointer(buf), pos - 1)
else
buf, pos = writeshortest(x, Vector{UInt8}(undef, shortestdigits(T)), 1)
buf = Vector{UInt8}(undef, shortestdigits(T))
pos = writeshortest(x, buf, 1)
GC.@preserve buf unsafe_write(io, pointer(buf), pos - 1)
end
return
Expand Down
8 changes: 4 additions & 4 deletions base/ryu/exp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,20 @@
buf[pos + 1] = UInt8('+')
buf[pos + 2] = UInt8('0')
buf[pos + 3] = UInt8('0')
return buf, pos + 4
return pos + 4
elseif isnan(x)
buf[pos] = UInt8('N')
buf[pos + 1] = UInt8('a')
buf[pos + 2] = UInt8('N')
return buf, pos + 3
return pos + 3
elseif !isfinite(x)
if neg
buf[pos] = UInt8('-')
end
buf[pos + neg] = UInt8('I')
buf[pos + neg + 1] = UInt8('n')
buf[pos + neg + 2] = UInt8('f')
return buf, pos + neg + 3
return pos + neg + 3
end

bits = Core.bitcast(UInt64, x)
Expand Down Expand Up @@ -212,5 +212,5 @@
unsafe_copyto!(buf, pos, DIGIT_TABLE, 2 * e + 1, 2)
pos += 2
end
return buf, pos
return pos
end
8 changes: 4 additions & 4 deletions base/ryu/fixed.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,20 @@
pos += 1
end
end
return buf, pos
return pos
elseif isnan(x)
buf[pos] = UInt8('N')
buf[pos + 1] = UInt8('a')
buf[pos + 2] = UInt8('N')
return buf, pos + 3
return pos + 3
elseif !isfinite(x)
if neg
buf[pos] = UInt8('-')
end
buf[pos + neg] = UInt8('I')
buf[pos + neg + 1] = UInt8('n')
buf[pos + neg + 2] = UInt8('f')
return buf, pos + neg + 3
return pos + neg + 3
end

bits = Core.bitcast(UInt64, x)
Expand Down Expand Up @@ -170,5 +170,5 @@
pos += 1
end
end
return buf, pos
return pos
end
126 changes: 82 additions & 44 deletions base/ryu/shortest.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,20 @@
buf[pos + neg] = UInt8('0')
buf[pos + neg + 1] = UInt8('.')
buf[pos + neg + 2] = UInt8('0')
return buf, pos + neg + 3
return pos + neg + 3
elseif isnan(x)
buf[pos] = UInt8('N')
buf[pos + 1] = UInt8('a')
buf[pos + 2] = UInt8('N')
return buf, pos + 3
return pos + 3
elseif !isfinite(x)
if neg
buf[pos] = UInt8('-')
end
buf[pos + neg] = UInt8('I')
buf[pos + neg + 1] = UInt8('n')
buf[pos + neg + 2] = UInt8('f')
return buf, pos + neg + 3
return pos + neg + 3
end

bits = uint(x)
Expand Down Expand Up @@ -176,77 +176,115 @@
end
olength = decimallength(output)

exp_form = true
pt = nexp + olength
if -4 < pt < 6 && !(pt >= olength && abs(mod(x + 0.05, 10^(pt - olength)) - 0.05) > 0.05)
exp_form = false
# print out digits and decimal point fully
if nexp >= 0
buf[pos + nexp + olength] = UInt8('.')
buf[pos + nexp + olength + 1] = UInt8('0')
elseif abs(nexp) >= olength
buf[pos] = UInt8('0')
buf[pos + 1] = UInt8('.')
pos += 2
for _ = 1:(abs(nexp) - olength)
buf[pos] = UInt8('0')
pos += 1
end
end
else
pos += 1
end
i = 0
ptr = pointer(buf)
ptr2 = pointer(DIGIT_TABLE)
if (output >> 32) != 0
q = output ÷ 100000000
output2 = (output % UInt32) - UInt32(100000000) * (q % UInt32)
output = q

c = output2 % 10000
output2 = div(output2, 10000)
d = output2 % 10000
c = output2 % UInt32(10000)
output2 = div(output2, UInt32(10000))
d = output2 % UInt32(10000)
c0 = (c % 100) << 1
c1 = (c ÷ 100) << 1
d0 = (d % 100) << 1
d1 = (d ÷ 100) << 1
unsafe_copyto!(buf, pos + olength - 1, DIGIT_TABLE, c0 + 1, 2)
unsafe_copyto!(buf, pos + olength - 3, DIGIT_TABLE, c1 + 1, 2)
unsafe_copyto!(buf, pos + olength - 5, DIGIT_TABLE, d0 + 1, 2)
unsafe_copyto!(buf, pos + olength - 7, DIGIT_TABLE, d1 + 1, 2)
memcpy(ptr, pos + olength - 2, ptr2, c0 + 1, 2)
memcpy(ptr, pos + olength - 4, ptr2, c1 + 1, 2)
memcpy(ptr, pos + olength - 6, ptr2, d0 + 1, 2)
memcpy(ptr, pos + olength - 8, ptr2, d1 + 1, 2)
i += 8
end
output2 = output % UInt32
while output2 >= 10000
c = output2 % 10000
output2 = div(output2, 10000)
c = output2 % UInt32(10000)
output2 = div(output2, UInt32(10000))
c0 = (c % 100) << 1
c1 = (c ÷ 100) << 1
unsafe_copyto!(buf, pos + olength - i - 1, DIGIT_TABLE, c0 + 1, 2)
unsafe_copyto!(buf, pos + olength - i - 3, DIGIT_TABLE, c1 + 1, 2)
memcpy(ptr, pos + olength - i - 2, ptr2, c0 + 1, 2)
memcpy(ptr, pos + olength - i - 4, ptr2, c1 + 1, 2)
i += 4
end
if output2 >= 100
c = (output2 % 100) << 1
output2 = div(output2, 100)
unsafe_copyto!(buf, pos + olength - i - 1, DIGIT_TABLE, c + 1, 2)
c = (output2 % UInt32(100)) << 1
output2 = div(output2, UInt32(100))
memcpy(ptr, pos + olength - i - 2, ptr2, c + 1, 2)
i += 2
end
if output2 >= 10
c = output2 << 1
#=@inbounds=# buf[pos + olength - i] = DIGIT_TABLE[c + 2]
#=@inbounds=# buf[pos] = DIGIT_TABLE[c + 1]
#=@inbounds=# buf[pos + 1] = DIGIT_TABLE[c + 2]
#=@inbounds=# buf[pos - exp_form] = DIGIT_TABLE[c + 1]
else
#=@inbounds=# buf[pos] = UInt8('0') + (output2 % UInt8)
#=@inbounds=# buf[pos - exp_form] = UInt8('0') + (output2 % UInt8)
end

if olength > 1
#=@inbounds=# buf[pos + 1] = UInt8('.')
pos += olength + 1
if !exp_form
if nexp >= 0
pos += olength
for _ = 1:nexp
buf[pos] = UInt8('0')
pos += 1
end
pos += 2
elseif olength > abs(nexp)
pointoff = olength - abs(nexp)
memmove(ptr, pos + pointoff + 1, ptr, pos + pointoff, olength - pointoff + 1)
buf[pos + pointoff] = UInt8('.')
pos += olength + 1
else
pos += olength
end
else
pos += 1
end
if olength > 1
#=@inbounds=# buf[pos] = UInt8('.')
pos += olength
end

#=@inbounds=# buf[pos] = UInt8('e')
pos += 1
exp2 = nexp + olength - 1
if exp2 < 0
#=@inbounds=# buf[pos] = UInt8('-')
#=@inbounds=# buf[pos] = UInt8('e')
pos += 1
exp2 = -exp2
end
exp2 = nexp + olength - 1
if exp2 < 0
#=@inbounds=# buf[pos] = UInt8('-')
pos += 1
exp2 = -exp2
end

if exp2 >= 100
c = exp2 % 10
unsafe_copyto!(buf, pos, DIGIT_TABLE, 2 * div(exp2, 10) + 1, 2)
#=@inbounds=# buf[pos + 2] = UInt8('0') + (c % UInt8)
pos += 3
elseif exp2 >= 10
unsafe_copyto!(buf, pos, DIGIT_TABLE, 2 * exp2 + 1, 2)
pos += 2
else
#=@inbounds=# buf[pos] = UInt8('0') + (exp2 % UInt8)
pos += 1
if exp2 >= 100
c = exp2 % 10
memcpy(ptr, pos, ptr2, 2 * div(exp2, 10) + 1, 2)
#=@inbounds=# buf[pos + 2] = UInt8('0') + (c % UInt8)
pos += 3
elseif exp2 >= 10
memcpy(ptr, pos, ptr2, 2 * exp2 + 1, 2)
pos += 2
else
#=@inbounds=# buf[pos] = UInt8('0') + (exp2 % UInt8)
pos += 1
end
end

return buf, pos
return pos
end
15 changes: 9 additions & 6 deletions base/ryu/utils.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
const MANTISSA_MASK = 0x000fffffffffffff
const EXP_MASK = 0x00000000000007ff

memcpy(d, doff, s, soff, n) = ccall(:memcpy, Cvoid, (Ptr{UInt8}, Ptr{UInt8}, Int), d + doff - 1, s + soff - 1, n)
memmove(d, doff, s, soff, n) = ccall(:memmove, Cvoid, (Ptr{UInt8}, Ptr{UInt8}, Int), d + doff - 1, s + soff - 1, n)

uint(x::Float16) = Core.bitcast(UInt16, x)
uint(x::Float32) = Core.bitcast(UInt32, x)
uint(x::Float64) = Core.bitcast(UInt64, x)
Expand Down Expand Up @@ -36,9 +39,9 @@ qbound(::Type{Float64}) = 63
log10pow2(e) = (e * 78913) >> 18
log10pow5(e) = (e * 732923) >> 20
pow5bits(e) = ((e * 1217359) >> 19) + 1
mulshift(m::UInt64, mula, mulb, j) = ((((UInt128(m) * mula) >> 64) + UInt128(m) * mulb) >> (j - 64)) % UInt64
mulshift(m::UInt32, mul, j) = ((((UInt64(m) * (mul % UInt32)) >> 32) + (UInt64(m) * (mul >> 32))) >> (j - 32)) % UInt32
mulshift(m::UInt16, mul, j) = ((((UInt32(m) * (mul % UInt16)) >> 16) + (UInt32(m) * (mul >> 16))) >> (j - 16))
@inline mulshift(m::UInt64, mula, mulb, j) = ((((UInt128(m) * mula) >> 64) + UInt128(m) * mulb) >> (j - 64)) % UInt64
@inline mulshift(m::UInt32, mul, j) = ((((UInt64(m) * (mul % UInt32)) >> 32) + (UInt64(m) * (mul >> 32))) >> (j - 32)) % UInt32
@inline mulshift(m::UInt16, mul, j) = ((((UInt32(m) * (mul % UInt16)) >> 16) + (UInt32(m) * (mul >> 16))) >> (j - 16))
indexforexp(e) = div(e + 15, 16)
pow10bitsforindex(idx) = 16 * idx + 120
lengthforindex(idx) = div((((16 * idx) * 1292913986) >> 32) + 1 + 16 + 8, 9)
Expand Down Expand Up @@ -284,7 +287,7 @@ const BIG_MASK = (big(1) << 64) - 1

const POW10_SPLIT = collect(Iterators.flatten(map(0:63) do idx
pow10bits = pow10bitsforindex(idx)
map(0:lengthforindex(idx)-1) do i
map(0:lengthforindex(idx) - 1) do i
v = (div(big(1) << pow10bits, big(10)^(9 * i)) + 1) % ((big(10)^9) << 136)
return (UInt64(v & BIG_MASK), UInt64((v >> 64) & BIG_MASK), UInt64((v >> 128) & BIG_MASK))
end
Expand Down Expand Up @@ -325,7 +328,7 @@ bitlength(this) = Base.GMP.MPZ.sizeinbase(this, 2)
@inline function pow5invsplit(::Type{Float64}, i)
pow = big(5)^i
inv = div(big(1) << (bitlength(pow) - 1 + pow5_inv_bitcount(Float64)), pow) + 1
return (inv & ((big(1) << 64) - 1), inv >> 64)
return (UInt64(inv & ((big(1) << 64) - 1)), UInt64(inv >> 64))
end

@inline function pow5invsplit(::Type{Float32}, i)
Expand All @@ -343,7 +346,7 @@ end
@inline function pow5split(::Type{Float64}, i)
pow = big(5)^i
j = bitlength(pow) - pow5_bitcount(Float64)
return ((pow >> j) & ((big(1) << 64) - 1), pow >> (j + 64))
return (UInt64((pow >> j) & ((big(1) << 64) - 1)), UInt64(pow >> (j + 64)))
end

@inline function pow5split(::Type{Float32}, i)
Expand Down
Loading

0 comments on commit cc5df43

Please sign in to comment.