From 1aac6c690154db8273ce446066407fc92284d9c3 Mon Sep 17 00:00:00 2001 From: John M Kuhn Date: Fri, 15 Mar 2019 09:36:44 -0400 Subject: [PATCH 1/6] Use primitive type --- src/DecFP.jl | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/DecFP.jl b/src/DecFP.jl index 1a2799f..34a6507 100644 --- a/src/DecFP.jl +++ b/src/DecFP.jl @@ -112,11 +112,8 @@ Base.Rounding.setrounding(::Type{T}, r::RoundingMode) where {T<:DecimalFloatingP for w in (32,64,128) BID = Symbol(string("Dec",w)) Ti = Symbol(string("UInt",w)) - @eval struct $BID <: DecimalFloatingPoint - x::$Ti - $BID(x::Number) = convert($BID, x) - Base.reinterpret(::Type{$BID}, x::$Ti) = new(x) - end + @eval primitive type $BID <: DecimalFloatingPoint $w end + $BID(x::Number) = convert($BID, x) @eval function $BID(x::Real, mode::RoundingMode) setrounding($BID, mode) do @@ -494,7 +491,7 @@ for w in (32,64,128) Base.one(::Union{Type{$BID},$BID}) = $(_parse(T, "1")) Base.zero(::Union{Type{$BID},$BID}) = $(_parse(T, "0")) - Base.signbit(x::$BID) = $(zero(Ti)) != $(Ti(1) << (Ti(w - 1))) & x.x + Base.signbit(x::$BID) = $(zero(Ti)) != $(Ti(1) << (Ti(w - 1))) & reinterpret($Ti, x) Base.sign(x::$BID) = ifelse(isnan(x) || iszero(x), x, ifelse(signbit(x), $(_parse(T, "-1")), $(_parse(T, "1")))) Base.nextfloat(x::$BID) = nox(_nextfloat(x)) @@ -616,10 +613,9 @@ for w in (32,64,128) end end - @eval Base.bswap(x::$BID) = reinterpret($BID, bswap(x.x)) + @eval Base.bswap(x::$BID) = reinterpret($BID, bswap(reinterpret($Ti, x))) @eval Base.convert(::Type{Float16}, x::$BID) = convert(Float16, convert(Float32, x)) @eval Base.Float16(x::$BID) = convert(Float16, x) - @eval Base.reinterpret(::Type{$Ti}, x::$BID) = x.x end # widths w Base.round(x::DecimalFloatingPoint, ::RoundingMode{:FromZero}) = signbit(x) ? floor(x) : ceil(x) From 008996a2f6468cf75f9b484a807175e5067dc110 Mon Sep 17 00:00:00 2001 From: John M Kuhn Date: Sat, 11 May 2019 13:12:38 -0400 Subject: [PATCH 2/6] Use struct for Dec128 --- src/DecFP.jl | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/DecFP.jl b/src/DecFP.jl index 34a6507..9231f38 100644 --- a/src/DecFP.jl +++ b/src/DecFP.jl @@ -109,11 +109,18 @@ Base.Rounding.rounding(::Type{T}) where {T<:DecimalFloatingPoint} = Base.Rounding.setrounding(::Type{T}, r::RoundingMode) where {T<:DecimalFloatingPoint} = Base.Rounding.setrounding_raw(T, convert(DecFPRoundingMode, r)) +primitive type Dec32 <: DecimalFloatingPoint 32 end +primitive type Dec64 <: DecimalFloatingPoint 64 end +Dec32(x::Number) = convert(Dec32, x) +Dec64(x::Number) = convert(Dec64, x) +struct Dec128 <: DecimalFloatingPoint + x::UInt128 + Dec128(x::Number) = convert(Dec128, x) + Base.reinterpret(::Type{Dec128}, x::UInt128) = new(x) +end for w in (32,64,128) BID = Symbol(string("Dec",w)) Ti = Symbol(string("UInt",w)) - @eval primitive type $BID <: DecimalFloatingPoint $w end - $BID(x::Number) = convert($BID, x) @eval function $BID(x::Real, mode::RoundingMode) setrounding($BID, mode) do @@ -613,11 +620,15 @@ for w in (32,64,128) end end - @eval Base.bswap(x::$BID) = reinterpret($BID, bswap(reinterpret($Ti, x))) @eval Base.convert(::Type{Float16}, x::$BID) = convert(Float16, convert(Float32, x)) @eval Base.Float16(x::$BID) = convert(Float16, x) end # widths w +Base.reinterpret(::Type{UInt128}, x::Dec128) = x.x +Base.bswap(x::Dec32) = reinterpret(Dec32, bswap(reinterpret(UInt32, x))) +Base.bswap(x::Dec64) = reinterpret(Dec64, bswap(reinterpret(UInt64, x))) +Base.bswap(x::Dec128) = reinterpret(Dec128, bswap(x.x)) + Base.round(x::DecimalFloatingPoint, ::RoundingMode{:FromZero}) = signbit(x) ? floor(x) : ceil(x) for (f) in (:trunc, :floor, :ceil) From 33669e5963114cb847a2f15dac7c1aa6137d260b Mon Sep 17 00:00:00 2001 From: "Steven G. Johnson" Date: Fri, 25 Mar 2022 15:59:35 -0400 Subject: [PATCH 3/6] use old struct approach on arm64 to prevent regression there --- src/DecFP.jl | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/DecFP.jl b/src/DecFP.jl index 9231f38..f594ea7 100644 --- a/src/DecFP.jl +++ b/src/DecFP.jl @@ -109,10 +109,23 @@ Base.Rounding.rounding(::Type{T}) where {T<:DecimalFloatingPoint} = Base.Rounding.setrounding(::Type{T}, r::RoundingMode) where {T<:DecimalFloatingPoint} = Base.Rounding.setrounding_raw(T, convert(DecFPRoundingMode, r)) -primitive type Dec32 <: DecimalFloatingPoint 32 end -primitive type Dec64 <: DecimalFloatingPoint 64 end -Dec32(x::Number) = convert(Dec32, x) -Dec64(x::Number) = convert(Dec64, x) +@static if Sys.ARCH == :arm64 + struct Dec32 <: DecimalFloatingPoint + x::UInt32 + Dec32(x::Number) = convert(Dec32, x) + Base.reinterpret(::Type{Dec32}, x::UInt32) = new(x) + end + struct Dec64 <: DecimalFloatingPoint + x::UInt64 + Dec64(x::Number) = convert(Dec64, x) + Base.reinterpret(::Type{Dec64}, x::UInt64) = new(x) + end +else + primitive type Dec32 <: DecimalFloatingPoint 32 end + primitive type Dec64 <: DecimalFloatingPoint 64 end + Dec32(x::Number) = convert(Dec32, x) + Dec64(x::Number) = convert(Dec64, x) +end struct Dec128 <: DecimalFloatingPoint x::UInt128 Dec128(x::Number) = convert(Dec128, x) From 21a87f123994c55adb938e4c545ad9ce4c344633 Mon Sep 17 00:00:00 2001 From: "Steven G. Johnson" Date: Fri, 25 Mar 2022 16:35:34 -0400 Subject: [PATCH 4/6] use Base.BinaryPlatforms --- src/DecFP.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DecFP.jl b/src/DecFP.jl index f594ea7..4aa4584 100644 --- a/src/DecFP.jl +++ b/src/DecFP.jl @@ -109,7 +109,7 @@ Base.Rounding.rounding(::Type{T}) where {T<:DecimalFloatingPoint} = Base.Rounding.setrounding(::Type{T}, r::RoundingMode) where {T<:DecimalFloatingPoint} = Base.Rounding.setrounding_raw(T, convert(DecFPRoundingMode, r)) -@static if Sys.ARCH == :arm64 +@static if isdefined(Base, :BinaryPlatforms) && Base.BinaryPlatforms.arch(Base.BinaryPlatforms.HostPlatform()) == "aarch64" struct Dec32 <: DecimalFloatingPoint x::UInt32 Dec32(x::Number) = convert(Dec32, x) From d4b20260b61bd353dbcf48c19fdded0ad52411d8 Mon Sep 17 00:00:00 2001 From: "Steven G. Johnson" Date: Fri, 25 Mar 2022 16:39:11 -0400 Subject: [PATCH 5/6] keep reinterpret and bswap consistent --- src/DecFP.jl | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/DecFP.jl b/src/DecFP.jl index 4aa4584..26b06f4 100644 --- a/src/DecFP.jl +++ b/src/DecFP.jl @@ -110,27 +110,37 @@ Base.Rounding.setrounding(::Type{T}, r::RoundingMode) where {T<:DecimalFloatingP Base.Rounding.setrounding_raw(T, convert(DecFPRoundingMode, r)) @static if isdefined(Base, :BinaryPlatforms) && Base.BinaryPlatforms.arch(Base.BinaryPlatforms.HostPlatform()) == "aarch64" + # primitive types aren't working yet on ARM64 for some reason? struct Dec32 <: DecimalFloatingPoint x::UInt32 Dec32(x::Number) = convert(Dec32, x) Base.reinterpret(::Type{Dec32}, x::UInt32) = new(x) end + Base.reinterpret(::Type{UInt32}, x::Dec32) = x.x + Base.bswap(x::Dec32) = reinterpret(Dec32, bswap(x.x)) struct Dec64 <: DecimalFloatingPoint x::UInt64 Dec64(x::Number) = convert(Dec64, x) Base.reinterpret(::Type{Dec64}, x::UInt64) = new(x) end + Base.reinterpret(::Type{UInt64}, x::Dec64) = x.x + Base.bswap(x::Dec64) = reinterpret(Dec64, bswap(x.x)) else primitive type Dec32 <: DecimalFloatingPoint 32 end primitive type Dec64 <: DecimalFloatingPoint 64 end Dec32(x::Number) = convert(Dec32, x) Dec64(x::Number) = convert(Dec64, x) + Base.bswap(x::Dec32) = reinterpret(Dec32, bswap(reinterpret(UInt32, x))) + Base.bswap(x::Dec64) = reinterpret(Dec64, bswap(reinterpret(UInt64, x))) end struct Dec128 <: DecimalFloatingPoint x::UInt128 Dec128(x::Number) = convert(Dec128, x) Base.reinterpret(::Type{Dec128}, x::UInt128) = new(x) end +Base.reinterpret(::Type{UInt128}, x::Dec128) = x.x +Base.bswap(x::Dec128) = reinterpret(Dec128, bswap(x.x)) + for w in (32,64,128) BID = Symbol(string("Dec",w)) Ti = Symbol(string("UInt",w)) @@ -637,11 +647,6 @@ for w in (32,64,128) @eval Base.Float16(x::$BID) = convert(Float16, x) end # widths w -Base.reinterpret(::Type{UInt128}, x::Dec128) = x.x -Base.bswap(x::Dec32) = reinterpret(Dec32, bswap(reinterpret(UInt32, x))) -Base.bswap(x::Dec64) = reinterpret(Dec64, bswap(reinterpret(UInt64, x))) -Base.bswap(x::Dec128) = reinterpret(Dec128, bswap(x.x)) - Base.round(x::DecimalFloatingPoint, ::RoundingMode{:FromZero}) = signbit(x) ? floor(x) : ceil(x) for (f) in (:trunc, :floor, :ceil) From 38927bbd9f519908cacef9ccdbcab6856b94d1e9 Mon Sep 17 00:00:00 2001 From: "Steven G. Johnson" Date: Fri, 25 Mar 2022 17:30:37 -0400 Subject: [PATCH 6/6] check for ARM on Julia 1.3 too --- src/DecFP.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DecFP.jl b/src/DecFP.jl index 26b06f4..60a8192 100644 --- a/src/DecFP.jl +++ b/src/DecFP.jl @@ -109,7 +109,7 @@ Base.Rounding.rounding(::Type{T}) where {T<:DecimalFloatingPoint} = Base.Rounding.setrounding(::Type{T}, r::RoundingMode) where {T<:DecimalFloatingPoint} = Base.Rounding.setrounding_raw(T, convert(DecFPRoundingMode, r)) -@static if isdefined(Base, :BinaryPlatforms) && Base.BinaryPlatforms.arch(Base.BinaryPlatforms.HostPlatform()) == "aarch64" +@static if Sys.ARCH == :arm64 || Sys.ARCH == :aarch64 || (isdefined(Base, :BinaryPlatforms) && Base.BinaryPlatforms.arch(Base.BinaryPlatforms.HostPlatform()) == "aarch64") # primitive types aren't working yet on ARM64 for some reason? struct Dec32 <: DecimalFloatingPoint x::UInt32