Skip to content

Commit

Permalink
Fix for printing typemin(Int32); extensive int printing tests.
Browse files Browse the repository at this point in the history
The core fix here is making the unsigned() function preserve
the size of its argument, which is safe since it is as value-
preserving as the function can be.

This commit also renames int2str as base and moves the base
argument to the first position. We should probably make a
corresponding change to parse_int, but I'll leave that for
another commit.
  • Loading branch information
StefanKarpinski committed Jun 19, 2012
1 parent 746ec7d commit a510289
Show file tree
Hide file tree
Showing 7 changed files with 198 additions and 80 deletions.
4 changes: 2 additions & 2 deletions base/floatfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ sqrt(x::Real) = sqrt(float(x))
sin(x::Real) = sin(float(x))
cos(x::Real) = cos(float(x))

num2hex(x::Float32) = int2str(boxui32(unbox32(x)),16, 8)
num2hex(x::Float64) = int2str(boxui64(unbox64(x)),16,16)
num2hex(x::Float32) = hex(boxui32(unbox32(x)),8)
num2hex(x::Float64) = hex(boxui64(unbox64(x)),16)

function hex2num(s::String)
if length(s) <= 8
Expand Down
18 changes: 7 additions & 11 deletions base/int.jl
Original file line number Diff line number Diff line change
Expand Up @@ -143,25 +143,21 @@ convert(::Type{Uint128}, x::Int128 ) = box(Uint128,unbox(Uint128,x))
convert(::Type{Integer}, x::Float32) = convert(Int, x)
convert(::Type{Integer}, x::Float64) = convert(Int64, x)

convert(::Type{Signed}, x::Bool ) = convert(Int, x)
convert(::Type{Signed}, x::Char ) = convert(Int, x)
convert(::Type{Signed}, x::Uint8 ) = convert(Int, x)
convert(::Type{Signed}, x::Uint16 ) = convert(Int, x)
convert(::Type{Signed}, x::Uint32 ) = convert(Int, x)
convert(::Type{Signed}, x::Float32) = convert(Int, x)
convert(::Type{Signed}, x::Uint64 ) = convert(Int64, x)
convert(::Type{Signed}, x::Float64) = convert(Int64, x)
convert(::Type{Signed}, x::Uint128) = convert(Int128, x)
convert(::Type{Signed}, x::Float32) = convert(Int, x)
convert(::Type{Signed}, x::Float64) = convert(Int64, x)

convert(::Type{Unsigned}, x::Bool ) = convert(Uint, x)
convert(::Type{Unsigned}, x::Char ) = convert(Uint, x)
convert(::Type{Unsigned}, x::Int8 ) = convert(Uint, x)
convert(::Type{Unsigned}, x::Int16 ) = convert(Uint, x)
convert(::Type{Unsigned}, x::Int32 ) = convert(Uint, x)
convert(::Type{Unsigned}, x::Float32) = convert(Uint, x)
convert(::Type{Unsigned}, x::Int8 ) = convert(Uint8, x)
convert(::Type{Unsigned}, x::Int16 ) = convert(Uint16, x)
convert(::Type{Unsigned}, x::Int32 ) = convert(Uint32, x)
convert(::Type{Unsigned}, x::Int64 ) = convert(Uint64, x)
convert(::Type{Unsigned}, x::Float64) = convert(Uint64, x)
convert(::Type{Unsigned}, x::Int128 ) = convert(Uint128, x)
convert(::Type{Unsigned}, x::Float32) = convert(Uint, x)
convert(::Type{Unsigned}, x::Float64) = convert(Uint64, x)

int8 (x) = convert(Int8, x)
int16 (x) = convert(Int16, x)
Expand Down
49 changes: 34 additions & 15 deletions base/intfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -217,14 +217,7 @@ ndigits(x::Integer) = ndigits(unsigned(abs(x)))

## integer to string functions ##

macro _jl_int_stringifier(sym)
quote
($sym)(x::Unsigned, p::Int) = ($sym)(x,p,false)
($sym)(x::Unsigned) = ($sym)(x,1,false)
($sym)(x::Integer, p::Int) = ($sym)(unsigned(abs(x)),p,x<0)
($sym)(x::Integer) = ($sym)(unsigned(abs(x)),1,x<0)
end
end
const _jl_dig_syms = "0123456789abcdefghijklmnopqrstuvwxyz".data

function bin(x::Unsigned, pad::Int, neg::Bool)
i = neg + max(pad,sizeof(x)<<3-leading_zeros(x))
Expand Down Expand Up @@ -254,7 +247,7 @@ function dec(x::Unsigned, pad::Int, neg::Bool)
i = neg + max(pad,ndigits0z(x))
a = Array(Uint8,i)
while i > neg
a[i] = '0'+mod(x,10)
a[i] = '0'+rem(x,10)
x = div(x,10)
i -= 1
end
Expand All @@ -266,24 +259,50 @@ function hex(x::Unsigned, pad::Int, neg::Bool)
i = neg + max(pad,(sizeof(x)<<1)-(leading_zeros(x)>>2))
a = Array(Uint8,i)
while i > neg
a[i] = _jl_hex_symbols[(x&0xf)+1]
a[i] = _jl_dig_syms[(x&0xf)+1]
x >>= 4
i -= 1
end
if neg; a[1]='-'; end
ASCIIString(a)
end

function base(b::Int, x::Unsigned, pad::Int, neg::Bool)
i = neg + max(pad,ndigits0z(x,b))
a = Array(Uint8,i)
while i > neg
a[i] = _jl_dig_syms[rem(x,b)+1]
x = div(x,b)
i -= 1
end
if neg; a[1]='-'; end
ASCIIString(a)
end

base(b::Int, x::Unsigned, p::Int) = base(b,x,p,false)
base(b::Int, x::Unsigned) = base(b,x,1,false)
base(b::Int, x::Integer, p::Int) = base(b,unsigned(abs(x)),p,x<0)
base(b::Int, x::Integer) = base(b,unsigned(abs(x)),1,x<0)

macro _jl_int_stringifier(sym)
quote
($sym)(x::Unsigned, p::Int) = ($sym)(x,p,false)
($sym)(x::Unsigned) = ($sym)(x,1,false)
($sym)(x::Integer, p::Int) = ($sym)(unsigned(abs(x)),p,x<0)
($sym)(x::Integer) = ($sym)(unsigned(abs(x)),1,x<0)
end
end

@_jl_int_stringifier bin
@_jl_int_stringifier oct
@_jl_int_stringifier dec
@_jl_int_stringifier hex

bits(x::Union(Bool,Int8,Uint8)) = bin(reinterpret(Uint8 ,x), 8)
bits(x::Union(Int16,Uint16)) = bin(reinterpret(Uint16 ,x), 16)
bits(x::Union(Char,Int32,Uint32,Float32)) = bin(reinterpret(Uint32 ,x), 32)
bits(x::Union(Int64,Uint64,Float64)) = bin(reinterpret(Uint64 ,x), 64)
bits(x::Union(Int128,Uint128)) = bin(reinterpret(Uint128,x), 128)
bits(x::Union(Bool,Int8,Uint8)) = bin(reinterpret(Uint8,x),8)
bits(x::Union(Int16,Uint16)) = bin(reinterpret(Uint16,x),16)
bits(x::Union(Char,Int32,Uint32,Float32)) = bin(reinterpret(Uint32,x),32)
bits(x::Union(Int64,Uint64,Float64)) = bin(reinterpret(Uint64,x),64)
bits(x::Union(Int128,Uint128)) = bin(reinterpret(Uint128,x),128)

const PRIMES = [
2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
Expand Down
41 changes: 0 additions & 41 deletions base/string.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1075,47 +1075,6 @@ uint64 (s::String) = parse_int(Uint64,s)
int128 (s::String) = parse_int(Int128,s)
uint128 (s::String) = parse_int(Uint128,s)

## integer to string functions ##

const _jl_dig_syms = "0123456789abcdefghijklmnopqrstuvwxyz".data

function int2str(n::Union(Int64,Uint64), b::Integer, l::Int)
if b < 2 || b > 36; error("int2str: invalid base ", b); end
neg = n < 0
n = unsigned(abs(n))
b = convert(typeof(n), b)
ndig = ndigits(n, b)
sz = max(convert(Int, ndig), l) + neg
data = Array(Uint8, sz)
i = sz
if ispow2(b)
digmask = b-1
shift = trailing_zeros(b)
while i > neg
ch = n & digmask
data[i] = _jl_dig_syms[int(ch)+1]
n >>= shift
i -= 1
end
else
while i > neg
ch = n % b
data[i] = _jl_dig_syms[int(ch)+1]
n = div(n,b)
i -= 1
end
end
if neg
data[1] = '-'
end
ASCIIString(data)
end
int2str(n::Integer, b::Integer) = int2str(n, b, 0)
int2str(n::Integer, b::Integer, l::Int) = int2str(int64(n), b, l)

string(x::Signed) = dec(int64(x))
cstring(x::Signed) = dec(int64(x))

## string to float functions ##

float64_isvalid(s::String, out::Array{Float64,1}) =
Expand Down
2 changes: 1 addition & 1 deletion doc/stdlib/base.rst
Original file line number Diff line number Diff line change
Expand Up @@ -783,7 +783,7 @@ Data Formats

Convert an integer to an octal string, optionally specifying a number of digits to pad to.

.. function:: int2str(n, base[, pad])
.. function:: base(b, n[, pad])

Convert an integer to a string in the given base, optionally specifying a number of digits to pad to.

Expand Down
154 changes: 154 additions & 0 deletions test/numbers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,160 @@
@assert 2. * 3. == 6.
@assert min(1.0,1) == 1

# definition and printing of extreme integers
@assert bin(typemin(Uint8)) == "0"
@assert bin(typemax(Uint8)) == "1"^8
@assert oct(typemin(Uint8)) == "0"
@assert oct(typemax(Uint8)) == "377"
@assert dec(typemin(Uint8)) == "0"
@assert dec(typemax(Uint8)) == "255"
@assert hex(typemin(Uint8)) == "0"
@assert hex(typemax(Uint8)) == "ff"
@assert string(typemin(Uint8)) == "0x00"
@assert string(typemax(Uint8)) == "0xff"
@assert base(3,typemin(Uint8)) == "0"
@assert base(3,typemax(Uint8)) == "100110"
@assert base(12,typemin(Uint8)) == "0"
@assert base(12,typemax(Uint8)) == "193"

@assert bin(typemin(Uint16)) == "0"
@assert bin(typemax(Uint16)) == "1"^16
@assert oct(typemin(Uint16)) == "0"
@assert oct(typemax(Uint16)) == "177777"
@assert dec(typemin(Uint16)) == "0"
@assert dec(typemax(Uint16)) == "65535"
@assert hex(typemin(Uint16)) == "0"
@assert hex(typemax(Uint16)) == "ffff"
@assert string(typemin(Uint16)) == "0x0000"
@assert string(typemax(Uint16)) == "0xffff"
@assert base(3,typemin(Uint16)) == "0"
@assert base(3,typemax(Uint16)) == "10022220020"
@assert base(12,typemin(Uint16)) == "0"
@assert base(12,typemax(Uint16)) == "31b13"

@assert bin(typemin(Uint32)) == "0"
@assert bin(typemax(Uint32)) == "1"^32
@assert oct(typemin(Uint32)) == "0"
@assert oct(typemax(Uint32)) == "37777777777"
@assert dec(typemin(Uint32)) == "0"
@assert dec(typemax(Uint32)) == "4294967295"
@assert hex(typemin(Uint32)) == "0"
@assert hex(typemax(Uint32)) == "ffffffff"
@assert string(typemin(Uint32)) == "0x00000000"
@assert string(typemax(Uint32)) == "0xffffffff"
@assert base(3,typemin(Uint32)) == "0"
@assert base(3,typemax(Uint32)) == "102002022201221111210"
@assert base(12,typemin(Uint32)) == "0"
@assert base(12,typemax(Uint32)) == "9ba461593"

@assert bin(typemin(Uint64)) == "0"
@assert bin(typemax(Uint64)) == "1"^64
@assert oct(typemin(Uint64)) == "0"
@assert oct(typemax(Uint64)) == "1777777777777777777777"
@assert dec(typemin(Uint64)) == "0"
@assert dec(typemax(Uint64)) == "18446744073709551615"
@assert hex(typemin(Uint64)) == "0"
@assert hex(typemax(Uint64)) == "ffffffffffffffff"
@assert string(typemin(Uint64)) == "0x0000000000000000"
@assert string(typemax(Uint64)) == "0xffffffffffffffff"
@assert base(3,typemin(Uint64)) == "0"
@assert base(3,typemax(Uint64)) == "11112220022122120101211020120210210211220"
@assert base(12,typemin(Uint64)) == "0"
@assert base(12,typemax(Uint64)) == "839365134a2a240713"

@assert bin(typemin(Uint128)) == "0"
@assert bin(typemax(Uint128)) == "1"^128
@assert oct(typemin(Uint128)) == "0"
@assert oct(typemax(Uint128)) == "3777777777777777777777777777777777777777777"
@assert dec(typemin(Uint128)) == "0"
@assert dec(typemax(Uint128)) == "340282366920938463463374607431768211455"
@assert hex(typemin(Uint128)) == "0"
@assert hex(typemax(Uint128)) == "ffffffffffffffffffffffffffffffff"
@assert string(typemin(Uint128)) == "0x00000000000000000000000000000000"
@assert string(typemax(Uint128)) == "0xffffffffffffffffffffffffffffffff"
@assert base(3,typemin(Uint128)) == "0"
@assert base(3,typemax(Uint128)) ==
"202201102121002021012000211012011021221022212021111001022110211020010021100121010"
@assert base(12,typemin(Uint128)) == "0"
@assert base(12,typemax(Uint128)) == "5916b64b41143526a777873841863a6a6993"

@assert bin(typemin(Int8)) == "-1"*"0"^7
@assert bin(typemax(Int8)) == "1"^7
@assert oct(typemin(Int8)) == "-200"
@assert oct(typemax(Int8)) == "177"
@assert dec(typemin(Int8)) == "-128"
@assert dec(typemax(Int8)) == "127"
@assert hex(typemin(Int8)) == "-80"
@assert hex(typemax(Int8)) == "7f"
@assert string(typemin(Int8)) == "-128"
@assert string(typemax(Int8)) == "127"
@assert base(3,typemin(Int8)) == "-11202"
@assert base(3,typemax(Int8)) == "11201"
@assert base(12,typemin(Int8)) == "-a8"
@assert base(12,typemax(Int8)) == "a7"

@assert bin(typemin(Int16)) == "-1"*"0"^15
@assert bin(typemax(Int16)) == "1"^15
@assert oct(typemin(Int16)) == "-100000"
@assert oct(typemax(Int16)) == "77777"
@assert dec(typemin(Int16)) == "-32768"
@assert dec(typemax(Int16)) == "32767"
@assert hex(typemin(Int16)) == "-8000"
@assert hex(typemax(Int16)) == "7fff"
@assert string(typemin(Int16)) == "-32768"
@assert string(typemax(Int16)) == "32767"
@assert base(3,typemin(Int16)) == "-1122221122"
@assert base(3,typemax(Int16)) == "1122221121"
@assert base(12,typemin(Int16)) == "-16b68"
@assert base(12,typemax(Int16)) == "16b67"

@assert bin(typemin(Int32)) == "-1"*"0"^31
@assert bin(typemax(Int32)) == "1"^31
@assert oct(typemin(Int32)) == "-20000000000"
@assert oct(typemax(Int32)) == "17777777777"
@assert dec(typemin(Int32)) == "-2147483648"
@assert dec(typemax(Int32)) == "2147483647"
@assert hex(typemin(Int32)) == "-80000000"
@assert hex(typemax(Int32)) == "7fffffff"
@assert string(typemin(Int32)) == "-2147483648"
@assert string(typemax(Int32)) == "2147483647"
@assert base(3,typemin(Int32)) == "-12112122212110202102"
@assert base(3,typemax(Int32)) == "12112122212110202101"
@assert base(12,typemin(Int32)) == "-4bb2308a8"
@assert base(12,typemax(Int32)) == "4bb2308a7"

@assert bin(typemin(Int64)) == "-1"*"0"^63
@assert bin(typemax(Int64)) == "1"^63
@assert oct(typemin(Int64)) == "-1000000000000000000000"
@assert oct(typemax(Int64)) == "777777777777777777777"
@assert dec(typemin(Int64)) == "-9223372036854775808"
@assert dec(typemax(Int64)) == "9223372036854775807"
@assert hex(typemin(Int64)) == "-8000000000000000"
@assert hex(typemax(Int64)) == "7fffffffffffffff"
@assert string(typemin(Int64)) == "-9223372036854775808"
@assert string(typemax(Int64)) == "9223372036854775807"
@assert base(3,typemin(Int64)) == "-2021110011022210012102010021220101220222"
@assert base(3,typemax(Int64)) == "2021110011022210012102010021220101220221"
@assert base(12,typemin(Int64)) == "-41a792678515120368"
@assert base(12,typemax(Int64)) == "41a792678515120367"

@assert bin(typemin(Int128)) == "-1"*"0"^127
@assert bin(typemax(Int128)) == "1"^127
@assert oct(typemin(Int128)) == "-2000000000000000000000000000000000000000000"
@assert oct(typemax(Int128)) == "1777777777777777777777777777777777777777777"
@assert dec(typemin(Int128)) == "-170141183460469231731687303715884105728"
@assert dec(typemax(Int128)) == "170141183460469231731687303715884105727"
@assert hex(typemin(Int128)) == "-80000000000000000000000000000000"
@assert hex(typemax(Int128)) == "7fffffffffffffffffffffffffffffff"
@assert string(typemin(Int128)) == "-170141183460469231731687303715884105728"
@assert string(typemax(Int128)) == "170141183460469231731687303715884105727"
@assert base(3,typemin(Int128)) ==
"-101100201022001010121000102002120122110122221010202000122201220121120010200022002"
@assert base(3,typemax(Int128)) ==
"101100201022001010121000102002120122110122221010202000122201220121120010200022001"
@assert base(12,typemin(Int128)) == "-2a695925806818735399a37a20a31b3534a8"
@assert base(12,typemax(Int128)) == "2a695925806818735399a37a20a31b3534a7"

# signs
@assert sign(1) == 1
@assert sign(-1) == -1
Expand Down
10 changes: 0 additions & 10 deletions test/strings.jl
Original file line number Diff line number Diff line change
Expand Up @@ -220,16 +220,6 @@ end
@assert_fails parse_int("2x")
@assert_fails parse_int("-")

# printing numbers
@assert string(uint32(-1)) == "0xffffffff"
@assert hex(0xffffffffffff) == "ffffffffffff"
@assert hex(0xffffffffffff+1) == "1000000000000"
@assert hex(typemax(Uint64)) == "ffffffffffffffff"

@assert int2str(typemin(Int64), 10) == "-9223372036854775808"
@assert int2str(typemin(Int16), 10) == "-32768"
@assert int2str(typemin(Int8 ), 10) == "-128"

# string manipulation
@assert strip("\t hi \n") == "hi"

Expand Down

0 comments on commit a510289

Please sign in to comment.