Skip to content

Commit 28653ee

Browse files
jmkuhnstevengj
andauthored
Use primitive type (#91)
* Use primitive type * Use struct for Dec128 * use old struct approach on arm64 to prevent regression there * use Base.BinaryPlatforms * keep reinterpret and bswap consistent * check for ARM on Julia 1.3 too Co-authored-by: Steven G. Johnson <[email protected]>
1 parent a677c85 commit 28653ee

File tree

1 file changed

+33
-8
lines changed

1 file changed

+33
-8
lines changed

src/DecFP.jl

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -109,14 +109,41 @@ Base.Rounding.rounding(::Type{T}) where {T<:DecimalFloatingPoint} =
109109
Base.Rounding.setrounding(::Type{T}, r::RoundingMode) where {T<:DecimalFloatingPoint} =
110110
Base.Rounding.setrounding_raw(T, convert(DecFPRoundingMode, r))
111111

112+
@static if Sys.ARCH == :arm64 || Sys.ARCH == :aarch64 || (isdefined(Base, :BinaryPlatforms) && Base.BinaryPlatforms.arch(Base.BinaryPlatforms.HostPlatform()) == "aarch64")
113+
# primitive types aren't working yet on ARM64 for some reason?
114+
struct Dec32 <: DecimalFloatingPoint
115+
x::UInt32
116+
Dec32(x::Number) = convert(Dec32, x)
117+
Base.reinterpret(::Type{Dec32}, x::UInt32) = new(x)
118+
end
119+
Base.reinterpret(::Type{UInt32}, x::Dec32) = x.x
120+
Base.bswap(x::Dec32) = reinterpret(Dec32, bswap(x.x))
121+
struct Dec64 <: DecimalFloatingPoint
122+
x::UInt64
123+
Dec64(x::Number) = convert(Dec64, x)
124+
Base.reinterpret(::Type{Dec64}, x::UInt64) = new(x)
125+
end
126+
Base.reinterpret(::Type{UInt64}, x::Dec64) = x.x
127+
Base.bswap(x::Dec64) = reinterpret(Dec64, bswap(x.x))
128+
else
129+
primitive type Dec32 <: DecimalFloatingPoint 32 end
130+
primitive type Dec64 <: DecimalFloatingPoint 64 end
131+
Dec32(x::Number) = convert(Dec32, x)
132+
Dec64(x::Number) = convert(Dec64, x)
133+
Base.bswap(x::Dec32) = reinterpret(Dec32, bswap(reinterpret(UInt32, x)))
134+
Base.bswap(x::Dec64) = reinterpret(Dec64, bswap(reinterpret(UInt64, x)))
135+
end
136+
struct Dec128 <: DecimalFloatingPoint
137+
x::UInt128
138+
Dec128(x::Number) = convert(Dec128, x)
139+
Base.reinterpret(::Type{Dec128}, x::UInt128) = new(x)
140+
end
141+
Base.reinterpret(::Type{UInt128}, x::Dec128) = x.x
142+
Base.bswap(x::Dec128) = reinterpret(Dec128, bswap(x.x))
143+
112144
for w in (32,64,128)
113145
BID = Symbol(string("Dec",w))
114146
Ti = Symbol(string("UInt",w))
115-
@eval struct $BID <: DecimalFloatingPoint
116-
x::$Ti
117-
$BID(x::Number) = convert($BID, x)
118-
Base.reinterpret(::Type{$BID}, x::$Ti) = new(x)
119-
end
120147

121148
@eval function $BID(x::Real, mode::RoundingMode)
122149
setrounding($BID, mode) do
@@ -494,7 +521,7 @@ for w in (32,64,128)
494521
Base.one(::Union{Type{$BID},$BID}) = $(_parse(T, "1"))
495522
Base.zero(::Union{Type{$BID},$BID}) = $(_parse(T, "0"))
496523

497-
Base.signbit(x::$BID) = $(zero(Ti)) != $(Ti(1) << (Ti(w - 1))) & x.x
524+
Base.signbit(x::$BID) = $(zero(Ti)) != $(Ti(1) << (Ti(w - 1))) & reinterpret($Ti, x)
498525
Base.sign(x::$BID) = ifelse(isnan(x) || iszero(x), x, ifelse(signbit(x), $(_parse(T, "-1")), $(_parse(T, "1"))))
499526

500527
Base.nextfloat(x::$BID) = nox(_nextfloat(x))
@@ -616,10 +643,8 @@ for w in (32,64,128)
616643
end
617644
end
618645

619-
@eval Base.bswap(x::$BID) = reinterpret($BID, bswap(x.x))
620646
@eval Base.convert(::Type{Float16}, x::$BID) = convert(Float16, convert(Float32, x))
621647
@eval Base.Float16(x::$BID) = convert(Float16, x)
622-
@eval Base.reinterpret(::Type{$Ti}, x::$BID) = x.x
623648
end # widths w
624649

625650
Base.round(x::DecimalFloatingPoint, ::RoundingMode{:FromZero}) = signbit(x) ? floor(x) : ceil(x)

0 commit comments

Comments
 (0)