diff --git a/NEWS.md b/NEWS.md index 4a52f28173a83..3a396acd85a3c 100644 --- a/NEWS.md +++ b/NEWS.md @@ -634,8 +634,9 @@ Library improvements * `IOBuffer` can take the `sizehint` keyword argument to suggest a capacity of the buffer ([#25944]). - * `trunc`, `floor`, `ceil`, `round`, and `signif` specify `base` using a - keyword argument. ([#26156]) + * `trunc`, `floor`, `ceil`, and `round` specify `digits`, `sigdigits` and `base` using + keyword arguments. ([#26156], [#26670]) + Compiler/Runtime improvements ----------------------------- @@ -1134,6 +1135,8 @@ Deprecated or removed * `isupper`, `islower`, `ucfirst` and `lcfirst` have been deprecated in favor of `isuppercase`, `islowercase`, `uppercasefirst` and `lowercasefirst`, respectively ([#26442]). + * `signif` has been deprecated in favor of the `sigdigits` keyword argument to `round`. + Command-line option changes --------------------------- @@ -1442,4 +1445,5 @@ Command-line option changes [#26286]: https://github.com/JuliaLang/julia/issues/26286 [#26436]: https://github.com/JuliaLang/julia/issues/26436 [#26442]: https://github.com/JuliaLang/julia/issues/26442 -[#26600]: https://github.com/JuliaLang/julia/issues/26600 \ No newline at end of file +[#26600]: https://github.com/JuliaLang/julia/issues/26600 +[#26670]: https://github.com/JuliaLang/julia/issues/26670 \ No newline at end of file diff --git a/base/complex.jl b/base/complex.jl index 80ef9edf7e803..f31c3a0c7d32e 100644 --- a/base/complex.jl +++ b/base/complex.jl @@ -941,7 +941,9 @@ atanh(z::Complex) = atanh(float(z)) #Rounding complex numbers #Requires two different RoundingModes for the real and imaginary components """ - round(z, RoundingModeReal, RoundingModeImaginary) + round(z::Complex[, RoundingModeReal, [RoundingModeImaginary]]) + round(z::Complex[, RoundingModeReal, [RoundingModeImaginary]]; digits=, base=10) + round(z::Complex[, RoundingModeReal, [RoundingModeImaginary]]; sigdigits=, base=10) Return the nearest integral value of the same type as the complex-valued `z` to `z`, breaking ties using the specified [`RoundingMode`](@ref)s. The first @@ -954,16 +956,11 @@ julia> round(3.14 + 4.5im) 3.0 + 4.0im ``` """ -function round(z::Complex{<:AbstractFloat}, ::RoundingMode{MR}, ::RoundingMode{MI}) where {MR,MI} - Complex(round(real(z), RoundingMode{MR}()), - round(imag(z), RoundingMode{MI}())) +function round(z::Complex, rr::RoundingMode=RoundNearest, ri::RoundingMode=rr; digits=nothing, sigdigits=nothing, base=10) + Complex(round(real(z), rr; digits=digits, sigdigits=sigdigits, base=base), + round(imag(z), ri; digits=digits, sigdigits=sigdigits, base=base)) end -round(z::Complex) = Complex(round(real(z)), round(imag(z))) -function round(z::Complex, digits::Integer; base::Integer = 10) - Complex(round(real(z), digits, base = base), - round(imag(z), digits, base = base)) -end float(z::Complex{<:AbstractFloat}) = z float(z::Complex) = Complex(float(real(z)), float(imag(z))) diff --git a/base/deprecated.jl b/base/deprecated.jl index 6527547584118..678af02ed95e3 100644 --- a/base/deprecated.jl +++ b/base/deprecated.jl @@ -1502,11 +1502,17 @@ end false) # PR 26156 -@deprecate trunc(x, digits, base) trunc(x, digits, base = base) -@deprecate floor(x, digits, base) floor(x, digits, base = base) -@deprecate ceil(x, digits, base) ceil(x, digits, base = base) -@deprecate round(x, digits, base) round(x, digits, base = base) -@deprecate signif(x, digits, base) signif(x, digits, base = base) +@deprecate trunc(x::Number, digits) trunc(x; digits=digits) +@deprecate floor(x::Number, digits) floor(x; digits=digits) +@deprecate ceil(x::Number, digits) ceil(x; digits=digits) +@deprecate round(x::Number, digits) round(x; digits=digits) +@deprecate signif(x::Number, digits) round(x; sigdigits=digits, base = base) + +@deprecate trunc(x::Number, digits, base) trunc(x; digits=digits, base = base) +@deprecate floor(x::Number, digits, base) floor(x; digits=digits, base = base) +@deprecate ceil(x::Number, digits, base) ceil(x; digits=digits, base = base) +@deprecate round(x::Number, digits, base) round(x; digits=digits, base = base) +@deprecate signif(x::Number, digits, base) round(x; sigdigits=digits, base = base) # issue #25965 @deprecate spawn(cmds::AbstractCmd) run(cmds, wait = false) diff --git a/base/exports.jl b/base/exports.jl index 15de30529884f..da60509c29b9a 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -324,7 +324,6 @@ export sign, signbit, signed, - signif, significand, sin, sinc, diff --git a/base/float.jl b/base/float.jl index f39d9a3679816..716dfa4d8a398 100644 --- a/base/float.jl +++ b/base/float.jl @@ -348,28 +348,26 @@ trunc(::Type{Integer}, x::Float64) = trunc(Int,x) trunc(::Type{T}, x::Float16) where {T<:Integer} = trunc(T, Float32(x)) # fallbacks -floor(::Type{T}, x::AbstractFloat) where {T<:Integer} = trunc(T,floor(x)) +floor(::Type{T}, x::AbstractFloat) where {T<:Integer} = trunc(T,_round(x, RoundDown)) floor(::Type{T}, x::Float16) where {T<:Integer} = floor(T, Float32(x)) -ceil(::Type{T}, x::AbstractFloat) where {T<:Integer} = trunc(T,ceil(x)) +ceil(::Type{T}, x::AbstractFloat) where {T<:Integer} = trunc(T,_round(x, RoundUp)) ceil(::Type{T}, x::Float16) where {T<:Integer} = ceil(T, Float32(x)) -round(::Type{T}, x::AbstractFloat) where {T<:Integer} = trunc(T,round(x)) +round(::Type{T}, x::AbstractFloat) where {T<:Integer} = trunc(T,_round(x, RoundNearest)) round(::Type{T}, x::Float16) where {T<:Integer} = round(T, Float32(x)) -trunc(x::Float64) = trunc_llvm(x) -trunc(x::Float32) = trunc_llvm(x) -trunc(x::Float16) = Float16(trunc(Float32(x))) +_round(x::Float64, r::RoundingMode{:ToZero}) = trunc_llvm(x) +_round(x::Float32, r::RoundingMode{:ToZero}) = trunc_llvm(x) +_round(x::Float64, r::RoundingMode{:Down}) = floor_llvm(x) +_round(x::Float32, r::RoundingMode{:Down}) = floor_llvm(x) +_round(x::Float64, r::RoundingMode{:Up}) = ceil_llvm(x) +_round(x::Float32, r::RoundingMode{:Up}) = ceil_llvm(x) +_round(x::Float64, r::RoundingMode{:Nearest}) = rint_llvm(x) +_round(x::Float32, r::RoundingMode{:Nearest}) = rint_llvm(x) -floor(x::Float64) = floor_llvm(x) -floor(x::Float32) = floor_llvm(x) -floor(x::Float16) = Float16(floor(Float32(x))) - -ceil(x::Float64) = ceil_llvm(x) -ceil(x::Float32) = ceil_llvm(x) -ceil(x::Float16) = Float16( ceil(Float32(x))) - -round(x::Float64) = rint_llvm(x) -round(x::Float32) = rint_llvm(x) -round(x::Float16) = Float16(round(Float32(x))) +_round(x::Float16, r::RoundingMode{:ToZero}) = Float16(_round(Float32(x), r)) +_round(x::Float16, r::RoundingMode{:Down}) = Float16(_round(Float32(x), r)) +_round(x::Float16, r::RoundingMode{:Up}) = Float16(_round(Float32(x), r)) +_round(x::Float16, r::RoundingMode{:Nearest}) = Float16(_round(Float32(x), r)) ## floating point promotions ## promote_rule(::Type{Float32}, ::Type{Float16}) = Float32 @@ -662,7 +660,7 @@ for Ti in (Int8, Int16, Int32, Int64, Int128, UInt8, UInt16, UInt32, UInt64, UIn end end function (::Type{$Ti})(x::$Tf) - if ($(Tf(typemin(Ti))) <= x <= $(Tf(typemax(Ti)))) && (trunc(x) == x) + if ($(Tf(typemin(Ti))) <= x <= $(Tf(typemax(Ti)))) && (_round(x, RoundToZero) == x) return unsafe_trunc($Ti,x) else throw(InexactError($(Expr(:quote,Ti.name.name)), $Ti, x)) @@ -683,7 +681,7 @@ for Ti in (Int8, Int16, Int32, Int64, Int128, UInt8, UInt16, UInt32, UInt64, UIn end end function (::Type{$Ti})(x::$Tf) - if ($(Tf(typemin(Ti))) <= x < $(Tf(typemax(Ti)))) && (trunc(x) == x) + if ($(Tf(typemin(Ti))) <= x < $(Tf(typemax(Ti)))) && (_round(x, RoundToZero) == x) return unsafe_trunc($Ti,x) else throw(InexactError($(Expr(:quote,Ti.name.name)), $Ti, x)) diff --git a/base/floatfuncs.jl b/base/floatfuncs.jl index 249c4ee4204fd..7a15934ed58a3 100644 --- a/base/floatfuncs.jl +++ b/base/floatfuncs.jl @@ -44,43 +44,51 @@ isinteger(x::AbstractFloat) = (x - trunc(x) == 0) """ round([T,] x, [r::RoundingMode]) - round(x, [digits; base = 10]) + round(x, [r::RoundingMode]; digits::Integer=0, base = 10) + round(x, [r::RoundingMode]; sigdigits::Integer, base = 10) -Rounds `x` to an integer value according to the provided -[`RoundingMode`](@ref), returning a value of the same type as `x`. When not -specifying a rounding mode the global mode will be used -(see [`rounding`](@ref)), which by default is round to the nearest integer -([`RoundNearest`](@ref) mode), with ties (fractional values of 0.5) being -rounded to the nearest even integer. +Rounds the number `x`. + +Without keyword arguments, `x` is rounded to an integer value, returning a value of type +`T`, or of the same type of `x` if no `T` is provided. An [`InexactError`](@ref) will be +thrown if the value is not representable by `T`, similar to [`convert`](@ref). + +If the `digits` keyword argument is provided, it rounds to the specified number of digits +after the decimal place (or before if negative), in base `base`. + +If the `sigdigits` keyword argument is provided, it rounds to the specified number of +significant digits, in base `base`. + +The [`RoundingMode`](@ref) `r` controls the direction of the rounding; the default is +[`RoundNearest`](@ref), which rounds to the nearest integer, with ties (fractional values +of 0.5) being rounded to the nearest even integer. Note that `round` may give incorrect +results if the global rounding mode is changed (see [`rounding`](@ref)). # Examples ```jldoctest julia> round(1.7) 2.0 +julia> round(Int, 1.7) +2 + julia> round(1.5) 2.0 julia> round(2.5) 2.0 -``` - -The optional [`RoundingMode`](@ref) argument will change how the number gets -rounded. -`round(T, x, [r::RoundingMode])` converts the result to type `T`, throwing an -[`InexactError`](@ref) if the value is not representable. - -`round(x, digits)` rounds to the specified number of digits after the decimal place (or -before if negative). `round(x, digits, base = base)` rounds using a base other than 10. - -# Examples -```jldoctest -julia> round(pi, 2) +julia> round(pi; digits=2) 3.14 -julia> round(pi, 3, base = 2) +julia> round(pi; digits=3, base=2) 3.125 + +julia> round(123.456; sigdigits=2) +120.0 + +julia> round(357.913; sigdigits=4, base=2) +352.0 ``` !!! note @@ -104,93 +112,93 @@ julia> round(pi, 3, base = 2) 1.2 ``` -See also [`signif`](@ref) for rounding to significant digits. +# Extensions + +To extend `round` to new numeric types, it is typically sufficient to define `Base._round(x::NewType, ::RoundingMode)`. """ round(T::Type, x) -round(x::Real, ::RoundingMode{:ToZero}) = trunc(x) -round(x::Real, ::RoundingMode{:Up}) = ceil(x) -round(x::Real, ::RoundingMode{:Down}) = floor(x) -# C-style round -function round(x::AbstractFloat, ::RoundingMode{:NearestTiesAway}) - y = trunc(x) - ifelse(x==y,y,trunc(2*x-y)) + +round(::Type{T}, x::AbstractFloat, r::RoundingMode{:ToZero}) where {T<:Integer} = trunc(T, x) +round(::Type{T}, x::AbstractFloat, r::RoundingMode) where {T<:Integer} = trunc(T, _round(x,r)) + +function round(x::Real, r::RoundingMode=RoundNearest; + digits::Union{Nothing,Integer}=nothing, sigdigits::Union{Nothing,Integer}=nothing, base=10) + isfinite(x) || return x + _round(x,r,digits,sigdigits,base) end -# Java-style round -function round(x::AbstractFloat, ::RoundingMode{:NearestTiesUp}) - y = floor(x) - ifelse(x==y,y,copysign(floor(2*x-y),x)) +trunc(x::Real; kwargs...) = round(x, RoundToZero; kwargs...) +floor(x::Real; kwargs...) = round(x, RoundDown; kwargs...) +ceil(x::Real; kwargs...) = round(x, RoundUp; kwargs...) + +_round(x, r::RoundingMode, digits::Nothing, sigdigits::Nothing, base) = _round(x, r) +_round(x::Integer, r::RoundingMode) = x + +# round x to multiples of 1/invstep +function _round_invstep(x, invstep, r::RoundingMode) + y = _round(x * invstep, r) / invstep + if !isfinite(y) + return x + end + return y +end + +# round x to multiples of step +function _round_step(x, step, r::RoundingMode) + # TODO: use div with rounding mode + y = _round(x / step, r) * step + if !isfinite(y) + if x > 0 + return (r == RoundUp ? oftype(x, Inf) : zero(x)) + elseif x < 0 + return (r == RoundDown ? -oftype(x, Inf) : -zero(x)) + else + return x + end + end + return y end -round(::Type{T}, x::AbstractFloat, r::RoundingMode) where {T<:Integer} = trunc(T,round(x,r)) -# adapted from Matlab File Exchange roundsd: http://www.mathworks.com/matlabcentral/fileexchange/26212 -# for round, og is the power of 10 relative to the decimal point -# for signif, og is the absolute power of 10 -# digits and base must be integers, x must be convertable to float +function _round(x, r::RoundingMode, digits::Integer, sigdigits::Nothing, base) + fx = float(x) + if digits >= 0 + invstep = oftype(fx, base)^digits + _round_invstep(fx, invstep, r) + else + step = oftype(fx, base)^-digits + _round_step(fx, step, r) + end +end -function _signif_og(x, digits, base) +hidigit(x::Integer, base) = ndigits0z(x, base) +function hidigit(x::Real, base) + iszero(x) && return 0 + fx = float(x) if base == 10 - e = floor(log10(abs(x)) - digits + 1.) - og = oftype(x, exp10(abs(e))) + return 1 + floor(Int, log10(abs(fx))) elseif base == 2 - e = exponent(abs(x)) - digits + 1. - og = oftype(x, exp2(abs(e))) + return 1 + exponent(x) else - e = floor(log(base, abs(x)) - digits + 1.) - og = oftype(x, float(base) ^ abs(e)) + return 1 + floor(Int, log(base, abs(fx))) end - return og, e end -""" - signif(x, digits; base = 10) - -Rounds (in the sense of [`round`](@ref)) `x` so that there are `digits` significant digits, under a -base `base` representation, default 10. +function _round(x, r::RoundingMode, digits::Nothing, sigdigits::Integer, base) + h = hidigit(x, base) + _round(x, r, sigdigits-h, nothing, base) +end -# Examples -```jldoctest -julia> signif(123.456, 2) -120.0 +_round(x, r::RoundingMode, digits::Integer, sigdigits::Integer, base) = + throw(ArgumentError("`round` cannot use both `digits` and `sigdigits` arguments.")) -julia> signif(357.913, 4, base = 2) -352.0 -``` -""" -function signif(x::Real, digits::Integer; base::Integer = 10) - digits < 1 && throw(DomainError(digits, "`digits` cannot be less than 1.")) - - x = float(x) - (x == 0 || !isfinite(x)) && return x - og, e = _signif_og(x, digits, base) - if e >= 0 # for numeric stability - r = round(x/og)*og - else - r = round(x*og)/og - end - !isfinite(r) ? x : r +# C-style round +function _round(x::AbstractFloat, ::RoundingMode{:NearestTiesAway}) + y = trunc(x) + ifelse(x==y,y,trunc(2*x-y)) end - -for f in (:round, :ceil, :floor, :trunc) - @eval begin - function ($f)(x::Real, digits::Integer; base::Integer = 10) - x = float(x) - og = convert(eltype(x),base)^digits - r = ($f)(x * og) / og - - if !isfinite(r) - if digits > 0 - return x - elseif x > 0 - return $(:ceil == f ? :(convert(eltype(x), Inf)) : :(zero(x))) - elseif x < 0 - return $(:floor == f ? :(-convert(eltype(x), Inf)) : :(-zero(x))) - else - return x - end - end - return r - end - end +# Java-style round +function _round(x::AbstractFloat, ::RoundingMode{:NearestTiesUp}) + y = floor(x) + ifelse(x==y,y,copysign(floor(2*x-y),x)) end # isapprox: approximate equality of numbers diff --git a/base/int.jl b/base/int.jl index 406fbc62ca052..c83345cc75b06 100644 --- a/base/int.jl +++ b/base/int.jl @@ -492,7 +492,9 @@ mod(x::Integer, ::Type{T}) where {T<:Integer} = rem(x, T) unsafe_trunc(::Type{T}, x::Integer) where {T<:Integer} = rem(x, T) """ - trunc([T,] x, [digits; base = 10]) + trunc([T,] x) + trunc(x; digits::Integer= [, base = 10]) + trunc(x; sigdigits::Integer= [, base = 10]) `trunc(x)` returns the nearest integral value of the same type as `x` whose absolute value is less than or equal to `x`. @@ -500,12 +502,14 @@ is less than or equal to `x`. `trunc(T, x)` converts the result to type `T`, throwing an `InexactError` if the value is not representable. -`digits` and `base` work as for [`round`](@ref). +`digits`, `sigdigits` and `base` work as for [`round`](@ref). """ function trunc end """ - floor([T,] x, [digits; base = 10]) + floor([T,] x) + floor(x; digits::Integer= [, base = 10]) + floor(x; sigdigits::Integer= [, base = 10]) `floor(x)` returns the nearest integral value of the same type as `x` that is less than or equal to `x`. @@ -513,12 +517,14 @@ equal to `x`. `floor(T, x)` converts the result to type `T`, throwing an `InexactError` if the value is not representable. -`digits` and `base` work as for [`round`](@ref). +`digits`, `sigdigits` and `base` work as for [`round`](@ref). """ function floor end """ - ceil([T,] x, [digits; base = 10]) + ceil([T,] x) + ceil(x; digits::Integer= [, base = 10]) + ceil(x; sigdigits::Integer= [, base = 10]) `ceil(x)` returns the nearest integral value of the same type as `x` that is greater than or equal to `x`. @@ -526,15 +532,10 @@ equal to `x`. `ceil(T, x)` converts the result to type `T`, throwing an `InexactError` if the value is not representable. -`digits` and `base` work as for [`round`](@ref). +`digits`, `sigdigits` and `base` work as for [`round`](@ref). """ function ceil end -round(x::Integer) = x -trunc(x::Integer) = x -floor(x::Integer) = x - ceil(x::Integer) = x - round(::Type{T}, x::Integer) where {T<:Integer} = convert(T, x) trunc(::Type{T}, x::Integer) where {T<:Integer} = convert(T, x) floor(::Type{T}, x::Integer) where {T<:Integer} = convert(T, x) diff --git a/stdlib/Pkg/test/pkg.jl b/stdlib/Pkg/test/pkg.jl index 5e2ea64e63abc..357580dad23af 100644 --- a/stdlib/Pkg/test/pkg.jl +++ b/stdlib/Pkg/test/pkg.jl @@ -151,7 +151,7 @@ temp_pkg_dir() do end LibGit2.with(LibGit2.GitRepo, Pkg.dir("Example3")) do repo LibGit2.add!(repo, "README.md") - test_sig = LibGit2.Signature("TEST", "TEST@TEST.COM", round(time(), 0), 0) + test_sig = LibGit2.Signature("TEST", "TEST@TEST.COM", round(time()), 0) LibGit2.commit(repo, "testmsg"; author=test_sig, committer=test_sig) end @@ -182,7 +182,7 @@ temp_pkg_dir() do test_commit = LibGit2.with(LibGit2.GitRepo, Pkg.dir("Example")) do repo LibGit2.add!(repo, "README.md") - test_sig = LibGit2.Signature("TEST", "TEST@TEST.COM", round(time(), 0), 0) + test_sig = LibGit2.Signature("TEST", "TEST@TEST.COM", round(time()), 0) LibGit2.commit(repo, "testmsg"; author=test_sig, committer=test_sig) end Pkg.checkout("Example") diff --git a/stdlib/Pkg3/src/precompile.jl b/stdlib/Pkg3/src/precompile.jl index e20ee5d367ea2..5d7d6ad1fbae5 100644 --- a/stdlib/Pkg3/src/precompile.jl +++ b/stdlib/Pkg3/src/precompile.jl @@ -544,7 +544,6 @@ precompile(Tuple{typeof(Base.replace_ref_end_!), Int64, Nothing}) precompile(Tuple{typeof(Base.replace_ref_end_!), LineNumberNode, Nothing}) precompile(Tuple{typeof(Base.repr), String}) precompile(Tuple{typeof(Base.reverseind), String, Int64}) -precompile(Tuple{typeof(Base.round), Float64, Int64}) precompile(Tuple{typeof(Base.round), Type{Int64}, Float64}) precompile(Tuple{typeof(Base.run), Base.Cmd, Tuple{Base.DevNullStream, Base.DevNullStream, Base.DevNullStream}}) precompile(Tuple{typeof(Base.setindex!), Array{Array{Base.BitArray{2}, 1}, 1}, Array{Any, 1}, Int64}) diff --git a/stdlib/Pkg3/test/repl.jl b/stdlib/Pkg3/test/repl.jl index 70d4a25fa3922..43d43f39a53e9 100644 --- a/stdlib/Pkg3/test/repl.jl +++ b/stdlib/Pkg3/test/repl.jl @@ -8,7 +8,7 @@ import LibGit2 include("utils.jl") -const TEST_SIG = LibGit2.Signature("TEST", "TEST@TEST.COM", round(time(), 0), 0) +const TEST_SIG = LibGit2.Signature("TEST", "TEST@TEST.COM", round(time()), 0) const TEST_PKG = (name = "Example", uuid = UUID("7876af07-990d-54b4-ab0e-23690620f79a")) function git_init_package(tmp, path) diff --git a/test/complex.jl b/test/complex.jl index 935e67a7e9de8..6dde71594ff53 100644 --- a/test/complex.jl +++ b/test/complex.jl @@ -893,13 +893,13 @@ end end @testset "round and float, PR #8291" begin - @test round(Complex(1.125, 0.875), 2) == Complex(1.12, 0.88) + @test round(Complex(1.125, 0.875), digits=2) == Complex(1.12, 0.88) @test round(Complex(1.5, 0.5), RoundDown, RoundUp) == Complex(1.0, 1.0) @test round.([1:5;] .+ im) == [1:5;] .+ im @test round.([1:5;] .+ 0.5im) == [1.0:5.0;] @test float(Complex(1, 2)) == Complex(1.0, 2.0) - @test round(float(Complex(π, ℯ)),3) == Complex(3.142, 2.718) + @test round(float(Complex(π, ℯ)), digits=3) == Complex(3.142, 2.718) end @testset "ComplexF16 arithmetic, PR #10003" begin diff --git a/test/floatfuncs.jl b/test/floatfuncs.jl index 00f1b25794154..36457118929c1 100644 --- a/test/floatfuncs.jl +++ b/test/floatfuncs.jl @@ -79,24 +79,24 @@ end @testset "significant digits" begin # (would be nice to have a smart vectorized # version of signif) - @test signif(123.456, 1) ≈ 100. - @test signif(123.456, 3) ≈ 123. - @test signif(123.456, 5) ≈ 123.46 - @test signif(123.456, 8, base = 2) ≈ 123.5 - @test signif(123.456, 2, base = 4) ≈ 128.0 - @test signif(0.0, 1) === 0.0 - @test signif(-0.0, 1) === -0.0 - @test signif(1.2, 2) === 1.2 - @test signif(1.0, 6) === 1.0 - @test signif(0.6, 1) === 0.6 - @test signif(7.262839104539736, 2) === 7.3 - @test isinf(signif(Inf, 3)) - @test isnan(signif(NaN, 3)) - @test signif(1.12312, 1000) === 1.12312 - @test signif(Float32(7.262839104539736), 3) === Float32(7.26) - @test signif(Float32(7.262839104539736), 4) === Float32(7.263) - @test signif(Float32(1.2), 3) === Float32(1.2) - @test signif(Float32(1.2), 5) === Float32(1.2) - @test signif(Float16(0.6), 2) === Float16(0.6) - @test signif(Float16(1.1), 70) === Float16(1.1) + @test round(123.456, sigdigits=1) ≈ 100. + @test round(123.456, sigdigits=3) ≈ 123. + @test round(123.456, sigdigits=5) ≈ 123.46 + @test round(123.456, sigdigits=8, base = 2) ≈ 123.5 + @test round(123.456, sigdigits=2, base = 4) ≈ 128.0 + @test round(0.0, sigdigits=1) === 0.0 + @test round(-0.0, sigdigits=1) === -0.0 + @test round(1.2, sigdigits=2) === 1.2 + @test round(1.0, sigdigits=6) === 1.0 + @test round(0.6, sigdigits=1) === 0.6 + @test round(7.262839104539736, sigdigits=2) === 7.3 + @test isinf(round(Inf, sigdigits=3)) + @test isnan(round(NaN, sigdigits=3)) + @test round(1.12312, sigdigits=1000) === 1.12312 + @test round(Float32(7.262839104539736), sigdigits=3) === Float32(7.26) + @test round(Float32(7.262839104539736), sigdigits=4) === Float32(7.263) + @test round(Float32(1.2), sigdigits=3) === Float32(1.2) + @test round(Float32(1.2), sigdigits=5) === Float32(1.2) + @test round(Float16(0.6), sigdigits=2) === Float16(0.6) + @test round(Float16(1.1), sigdigits=70) === Float16(1.1) end diff --git a/test/namedtuple.jl b/test/namedtuple.jl index a97591ee9a290..9f09e28ab30bd 100644 --- a/test/namedtuple.jl +++ b/test/namedtuple.jl @@ -72,7 +72,7 @@ end @test map(+, (x=1, y=2), (x=10, y=20)) == (x=11, y=22) @test_throws ArgumentError map(+, (x=1, y=2), (y=10, x=20)) @test map(string, (x=1, y=2)) == (x="1", y="2") -@test map(round, (x=1//3, y=Int), (x=3, y=2//3)) == (x=0.333, y=1) +@test map(round, (x=UInt, y=Int), (x=3.1, y=2//3)) == (x=UInt(3), y=1) @test merge((a=1, b=2), (a=10,)) == (a=10, b=2) @test merge((a=1, b=2), (a=10, z=20)) == (a=10, b=2, z=20) diff --git a/test/rounding.jl b/test/rounding.jl index fe6779e382cc2..c7b0c9dde2864 100644 --- a/test/rounding.jl +++ b/test/rounding.jl @@ -265,65 +265,65 @@ end # custom rounding and significant-digit ops @testset "rounding to digits relative to the decimal point" begin - @test round(pi,0) ≈ 3. - @test round(pi,1) ≈ 3.1 - @test round(10*pi,-1) ≈ 30. - @test round(.1,0) == 0. - @test round(-.1,0) == -0. - @test isnan(round(NaN, 2)) - @test isinf(round(Inf,2)) - @test isinf(round(-Inf,2)) + @test round(pi, digits=0) ≈ 3. + @test round(pi, digits=1) ≈ 3.1 + @test round(10*pi, digits=-1) ≈ 30. + @test round(.1, digits=0) == 0. + @test round(-.1, digits=0) == -0. + @test isnan(round(NaN, digits=2)) + @test isinf(round(Inf, digits=2)) + @test isinf(round(-Inf, digits=2)) end @testset "round vs trunc vs floor vs ceil" begin - @test round(123.456,1) ≈ 123.5 - @test round(-123.456,1) ≈ -123.5 - @test trunc(123.456,1) ≈ 123.4 - @test trunc(-123.456,1) ≈ -123.4 - @test ceil(123.456,1) ≈ 123.5 - @test ceil(-123.456,1) ≈ -123.4 - @test floor(123.456,1) ≈ 123.4 - @test floor(-123.456,1) ≈ -123.5 + @test round(123.456, digits=1) ≈ 123.5 + @test round(-123.456, digits=1) ≈ -123.5 + @test trunc(123.456, digits=1) ≈ 123.4 + @test trunc(-123.456, digits=1) ≈ -123.4 + @test ceil(123.456, digits=1) ≈ 123.5 + @test ceil(-123.456, digits=1) ≈ -123.4 + @test floor(123.456, digits=1) ≈ 123.4 + @test floor(-123.456, digits=1) ≈ -123.5 end @testset "rounding with too much (or too few) precision" begin for x in (12345.6789, 0, -12345.6789) y = float(x) - @test y == trunc(x, 1000) - @test y == round(x, 1000) - @test y == floor(x, 1000) - @test y == ceil(x, 1000) + @test y == trunc(x, digits=1000) + @test y == round(x, digits=1000) + @test y == floor(x, digits=1000) + @test y == ceil(x, digits=1000) end let x = 12345.6789 - @test 0.0 == trunc(x, -1000) - @test 0.0 == round(x, -1000) - @test 0.0 == floor(x, -1000) - @test Inf == ceil(x, -1000) + @test 0.0 == trunc(x, digits=-1000) + @test 0.0 == round(x, digits=-1000) + @test 0.0 == floor(x, digits=-1000) + @test Inf == ceil(x, digits=-1000) end let x = -12345.6789 - @test -0.0 == trunc(x, -1000) - @test -0.0 == round(x, -1000) - @test -Inf == floor(x, -1000) - @test -0.0 == ceil(x, -1000) + @test -0.0 == trunc(x, digits=-1000) + @test -0.0 == round(x, digits=-1000) + @test -Inf == floor(x, digits=-1000) + @test -0.0 == ceil(x, digits=-1000) end let x = 0.0 - @test 0.0 == trunc(x, -1000) - @test 0.0 == round(x, -1000) - @test 0.0 == floor(x, -1000) - @test 0.0 == ceil(x, -1000) + @test 0.0 == trunc(x, digits=-1000) + @test 0.0 == round(x, digits=-1000) + @test 0.0 == floor(x, digits=-1000) + @test 0.0 == ceil(x, digits=-1000) end end @testset "rounding in other bases" begin - @test round(pi, 2, base = 2) ≈ 3.25 - @test round(pi, 3, base = 2) ≈ 3.125 - @test round(pi, 3, base = 5) ≈ 3.144 + @test round(pi, digits = 2, base = 2) ≈ 3.25 + @test round(pi, digits = 3, base = 2) ≈ 3.125 + @test round(pi, digits = 3, base = 5) ≈ 3.144 end @testset "vectorized trunc/round/floor/ceil with digits/base argument" begin a = rand(2, 2, 2) for f in (round, trunc, floor, ceil) - @test f.(a[:, 1, 1], 2) == map(x->f(x, 2), a[:, 1, 1]) - @test f.(a[:, :, 1], 2) == map(x->f(x, 2), a[:, :, 1]) - @test f.(a, 9, base = 2) == map(x->f(x, 9, base = 2), a) - @test f.(a[:, 1, 1], 9, base = 2) == map(x->f(x, 9, base = 2), a[:, 1, 1]) - @test f.(a[:, :, 1], 9, base = 2) == map(x->f(x, 9, base = 2), a[:, :, 1]) - @test f.(a, 9, base = 2) == map(x->f(x, 9, base = 2), a) + @test f.(a[:, 1, 1], digits=2) == map(x->f(x, digits=2), a[:, 1, 1]) + @test f.(a[:, :, 1], digits=2) == map(x->f(x, digits=2), a[:, :, 1]) + @test f.(a, digits=9, base = 2) == map(x->f(x, digits=9, base = 2), a) + @test f.(a[:, 1, 1], digits=9, base = 2) == map(x->f(x, digits=9, base = 2), a[:, 1, 1]) + @test f.(a[:, :, 1], digits=9, base = 2) == map(x->f(x, digits=9, base = 2), a[:, :, 1]) + @test f.(a, digits=9, base = 2) == map(x->f(x, digits=9, base = 2), a) end end diff --git a/test/subtype.jl b/test/subtype.jl index 69150ee6fb34c..5e68998d34e33 100644 --- a/test/subtype.jl +++ b/test/subtype.jl @@ -1253,7 +1253,7 @@ for it = 1:5 global x_24305 = x_24305 + h end -@test round.(x_24305, 2) == [1.78, 1.42, 1.24] +@test round.(x_24305, digits=2) == [1.78, 1.42, 1.24] # PR #24399 let (t, e) = intersection_env(Tuple{Union{Int,Int8}}, Tuple{T} where T)