Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: deprecate hex2num and num2hex, alternative to #22088 #22203

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1350,6 +1350,25 @@ end
@deprecate srand(filename::AbstractString, n::Integer=4) srand(read!(filename, Array{UInt32}(Int(n))))
@deprecate MersenneTwister(filename::AbstractString) srand(MersenneTwister(0), read!(filename, Array{UInt32}(Int(4))))

# PR #22203
@deprecate num2hex(n::Union{Bool, Base.BitReal}) bits(n, hex)

"""
hex2num(str)

Convert a hexadecimal string to the floating point number it represents.
This function, which is inherently type-unstable, returns a `Float16`,
a `Float32`, or a `Float64` depending on the length of the string `str`
(note that this length must hence be no greater than 16).
"""
function hex2num(s::AbstractString)
depwarn("hex2num(s) is deprecated, use reinterpret(T::Type, s)", :hex2num)
l = length(s)
l > 16 && throw(ArgumentError("the length of the passed string must be <= 16, got $l"))
reinterpret(l <= 4 ? Float16 : l <= 8 ? Float32 : Float64, s)
end
export hex2num

# END 0.7 deprecations

# BEGIN 1.0 deprecations
Expand Down
57 changes: 0 additions & 57 deletions base/docs/helpdb/Base.jl
Original file line number Diff line number Diff line change
Expand Up @@ -76,21 +76,6 @@ Subtraction operator.
"""
-(x, y)

"""
bits(n)

A string giving the literal bit representation of a number.

```jldoctest
julia> bits(4)
"0000000000000000000000000000000000000000000000000000000000000100"

julia> bits(2.2)
"0100000000000001100110011001100110011001100110011001100110011010"
```
"""
bits

"""
getindex(type[, elements...])

Expand Down Expand Up @@ -565,18 +550,6 @@ original string, otherwise they must be from distinct character ranges.
"""
eachmatch

"""
num2hex(f)

Get a hexadecimal string of the binary representation of a floating point number.

```jldoctest
julia> num2hex(2.2)
"400199999999999a"
```
"""
num2hex

"""
truncate(file,n)

Expand Down Expand Up @@ -1121,13 +1094,6 @@ julia> bin(bswap(1))
"""
bswap

"""
maxintfloat(T)

The largest integer losslessly representable by the given floating-point DataType `T`.
"""
maxintfloat

"""
delete!(collection, key)

Expand Down Expand Up @@ -1360,13 +1326,6 @@ false
"""
isempty

"""
hex2num(str)

Convert a hexadecimal string to the floating point number it represents.
"""
hex2num

"""
InexactError()

Expand Down Expand Up @@ -2165,14 +2124,6 @@ Values for `String` can be of that type, or `Vector{UInt8}`.
"""
isvalid(T,value)

"""
unsigned(x) -> Unsigned

Convert a number to an unsigned integer. If the argument is signed, it is reinterpreted as
unsigned without checking for negative values.
"""
unsigned

"""
reverseind(v, i)

Expand Down Expand Up @@ -2297,14 +2248,6 @@ for sets of arbitrary objects.
"""
Set

"""
signed(x)

Convert a number to a signed integer. If the argument is unsigned, it is reinterpreted as
signed without checking for overflow.
"""
signed

"""
Val{c}

Expand Down
39 changes: 39 additions & 0 deletions base/essentials.jl
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,46 @@ convert(::Type{T}, x::T) where {T<:Tuple{Any,Vararg{Any}}} = x

oftype(x,c) = convert(typeof(x),c)

"""
unsigned(x) -> Unsigned

Convert a number to an unsigned integer. If the argument is signed, it is reinterpreted as
unsigned without checking for negative values.
See also [`signed`](@ref).

```jldoctest
julia> unsigned(12)
0x000000000000000c

julia> unsigned(2.0)
0x0000000000000002

julia> unsigned(2.2)
ERROR: InexactError()
[...]
```
"""
unsigned(x::Int) = reinterpret(UInt, x)

"""
signed(x)

Convert a number to a signed integer. If the argument is unsigned, it is reinterpreted as
signed without checking for overflow.
See also [`unsigned`](@ref).

```jldoctest
julia> signed(0xc)
12

julia> signed(2.0)
2

julia> signed(2.2)
ERROR: InexactError()
[...]
```
"""
signed(x::UInt) = reinterpret(Int, x)

# conversions used by ccall
Expand Down
2 changes: 0 additions & 2 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,6 @@ export
gamma,
gcd,
gcdx,
hex2num,
hypot,
imag,
inv,
Expand Down Expand Up @@ -378,7 +377,6 @@ export
nextpow2,
nextprod,
numerator,
num2hex,
one,
oneunit,
powermod,
Expand Down
19 changes: 5 additions & 14 deletions base/floatfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ signbit(x::Float64) = signbit(bitcast(Int64, x))
signbit(x::Float32) = signbit(bitcast(Int32, x))
signbit(x::Float16) = signbit(bitcast(Int16, x))

"""
maxintfloat(T)

The largest integer losslessly representable by the given floating-point DataType `T`.
"""
maxintfloat(::Type{Float64}) = 9007199254740992.
maxintfloat(::Type{Float32}) = Float32(16777216.)
maxintfloat(::Type{Float16}) = Float16(2048f0)
Expand All @@ -24,20 +29,6 @@ maxintfloat() = maxintfloat(Float64)

isinteger(x::AbstractFloat) = (x - trunc(x) == 0)

num2hex(x::Float16) = hex(bitcast(UInt16, x), 4)
num2hex(x::Float32) = hex(bitcast(UInt32, x), 8)
num2hex(x::Float64) = hex(bitcast(UInt64, x), 16)

function hex2num(s::AbstractString)
if length(s) <= 4
return bitcast(Float16, parse(UInt16, s, 16))
end
if length(s) <= 8
return bitcast(Float32, parse(UInt32, s, 16))
end
return bitcast(Float64, parse(UInt64, s, 16))
end

"""
round([T,] x, [digits, [base]], [r::RoundingMode])

Expand Down
45 changes: 45 additions & 0 deletions base/int.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,51 @@ const BitInteger = Union{BitInteger_types...}
const BitSigned64T = Union{Type{Int8}, Type{Int16}, Type{Int32}, Type{Int64}}
const BitUnsigned64T = Union{Type{UInt8}, Type{UInt16}, Type{UInt32}, Type{UInt64}}

const BitFloat_types = (Float16, Float32, Float64)
const BitFloat = Union{BitFloat_types...}
const BitReal_types = (BitInteger_types..., BitFloat_types...)
const BitReal = Union{BitReal_types...}

## integer signed-ness conversions

reinterpret(::Type{Unsigned}, x::BitInteger) = unsigned(x)
reinterpret(::Type{ Signed}, x::BitInteger) = signed(x)
reinterpret(::Type{Unsigned}, ::Type{Bool}) = UInt8
reinterpret(::Type{ Signed}, ::Type{Bool}) = Int8
reinterpret(::Type{Unsigned}, x::Bool) = x % UInt8
reinterpret(::Type{ Signed}, x::Bool) = x % Int8
reinterpret(::Type{Unsigned}, ::Type{Char}) = UInt32
reinterpret(::Type{ Signed}, ::Type{Char}) = Int32
reinterpret(::Type{Unsigned}, x::Char) = unsigned(x)
reinterpret(::Type{ Signed}, x::Char) = signed(x)

"""
unsigned(T::Type) -> UnsignedType

Return the return-type of `unsigned(x::T)`, so that `unsigned(x)::unsigned(typeof(x))`.

```jldoctest
julia> unsigned(Int64)
UInt64
```
"""
unsigned(::Type{T}) where {T<:Unsigned} = T

"""
signed(T::Type) -> SignedType

Return the return-type of `signed(x::T)`, so that `signed(x)::signed(typeof(x))`.

```jldoctest
julia> signed(UInt64)
Int64
```
"""
signed(::Type{T}) where {T<:Signed} = T

unsigned(::Type{<:Union{Bool,BitFloat}}) = UInt
signed( ::Type{<:Union{Bool,BitFloat}}) = Int

## integer comparisons ##

(<)(x::T, y::T) where {T<:BitSigned} = slt_int(x, y)
Expand Down
66 changes: 60 additions & 6 deletions base/intfuncs.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license

# this construction is not available when put in int.jl and running in Core
for (S,U,F) in zip(BitSigned_types, BitUnsigned_types,
(nothing, Float16, Float32, Float64, nothing))
@eval begin
unsigned(::Type{$S}) = $U
unsigned(::Type{$U}) = $U
signed( ::Type{$S}) = $S
signed( ::Type{$U}) = $S
reinterpret(::Type{Unsigned}, ::Type{$S}) = $U
reinterpret(::Type{Unsigned}, ::Type{$U}) = $U
reinterpret(::Type{Signed}, ::Type{$S}) = $S
reinterpret(::Type{Signed}, ::Type{$U}) = $S
end
F === nothing && continue
@eval begin
reinterpret(::Type{Unsigned}, ::Type{$F}) = $U
reinterpret(::Type{Signed}, ::Type{$F}) = $S
end
end

## number-theoretic functions ##

"""
Expand Down Expand Up @@ -483,7 +503,22 @@ function hex(x::Unsigned, pad::Int, neg::Bool)
String(a)
end

num2hex(n::Integer) = hex(n, sizeof(n)*2)
"""
reinterpret(T::Type, str::AbstractString, b=16)

Interprets a string as the bit representation of a
number of type `T`, encoded in base `b`.

```jldoctest
julia> reinterpret(Float64, "400199999999999a")
2.2

julia> reinterpret(Int32, "fffffffe")
-2
```
"""
reinterpret(::Type{T}, s::AbstractString, b=16) where {T<:Union{Bool,Char,BitReal}} =
reinterpret(T, parse(reinterpret(Unsigned, T), s, b))

const base36digits = ['0':'9';'a':'z']
const base62digits = ['0':'9';'A':'Z';'a':'z']
Expand Down Expand Up @@ -573,11 +608,30 @@ Convert an integer to a decimal string, optionally specifying a number of digits
"""
dec

bits(x::Union{Bool,Int8,UInt8}) = bin(reinterpret(UInt8,x),8)
bits(x::Union{Int16,UInt16,Float16}) = 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(n, fmt=bin)

A string giving the literal bit representation of a number.
The `fmt` function, which can be `bin` or `hex`,
determines the format used to represent those bits
respectively as a binary or hexadecimal string.

```jldoctest
julia> bits(4)
"0000000000000000000000000000000000000000000000000000000000000100"

julia> bits(4, hex)
"0000000000000004"

julia> bits(2.2)
"0100000000000001100110011001100110011001100110011001100110011010"

julia> bits(2.2, hex)
"400199999999999a"
```
"""
bits(n::Union{Bool,Char,BitReal}, fmt::Union{typeof(bin), typeof(hex)}=bin) =
fmt(reinterpret(Unsigned, n), sizeof(n)*(fmt === bin ? 8 : 2))

"""
digits([T<:Integer], n::Integer, base::T=10, pad::Integer=1)
Expand Down
9 changes: 1 addition & 8 deletions base/multinverses.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,10 @@

module MultiplicativeInverses

import Base: div, divrem, rem, unsigned
import Base: div, divrem, rem
using Base: IndexLinear, IndexCartesian, tail
export multiplicativeinverse

unsigned(::Type{Int8}) = UInt8
unsigned(::Type{Int16}) = UInt16
unsigned(::Type{Int32}) = UInt32
unsigned(::Type{Int64}) = UInt64
unsigned(::Type{Int128}) = UInt128
unsigned{T<:Unsigned}(::Type{T}) = T

abstract type MultiplicativeInverse{T} end

# Computes integer division by a constant using multiply, add, and bitshift.
Expand Down
2 changes: 0 additions & 2 deletions doc/src/stdlib/numbers.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,6 @@ Base.Math.significand
Base.Math.exponent
Base.complex(::Complex)
Base.bswap
Base.num2hex
Base.hex2num
Base.hex2bytes
Base.bytes2hex
```
Expand Down
4 changes: 2 additions & 2 deletions test/floatfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ for elty in (Float16,Float32,Float64)
@test !isinteger(elty(NaN))
end

# num2hex, hex2num
# bits, reinterpret
for elty in (Float16,Float32,Float64), _ = 1:10
x = rand(elty)
@test hex2num(num2hex(x)) ≈ x
@test reinterpret(elty, bits(x, hex)) ≈ x
end

# round
Expand Down
Loading