@@ -13,10 +13,10 @@ import Base: (*), +, -, /, <, <=, ==, ^, convert,
13
13
exp, expm1, log, log2, log10, log1p, sin, sinh, sqrt,
14
14
tan, tanh,
15
15
ceil, floor, trunc, round, fma,
16
- copysign, max, min, hypot,
17
- abs, imag, real, conj, angle, cis ,
18
- eps, isinf, isnan, isfinite,
19
- Int32,Int64,Float64
16
+ copysign, max, min, hypot, abs,
17
+ ldexp, frexp ,
18
+ eps, isinf, isnan, isfinite, floatmin, floatmax, precision, signbit,
19
+ Int32,Int64,Float64,BigFloat
20
20
21
21
if Sys. isapple ()
22
22
const quadoplib = " libquadmath.0"
@@ -185,11 +185,12 @@ isinf(x::Float128) =
185
185
isfinite (x:: Float128 ) =
186
186
0 != ccall ((:finiteq ,libquadmath), Cint, (Cfloat128, ), x)
187
187
188
- eps (:: Type{Float128} ) = reinterpret (Float128, 0x3f8f0000000000000000000000000000 )
189
- realmin (:: Type{Float128} ) = reinterpret (Float128, 0x00010000000000000000000000000000 )
190
- realmax (:: Type{Float128} ) = reinterpret (Float128, 0x7ffeffffffffffffffffffffffffffff )
191
- Float128 (:: Irrational{:π} ) = reinterpret (Float128, 0x4000921fb54442d18469898cc51701b8 )
192
- Float128 (:: Irrational{:e} ) = reinterpret (Float128, 0x40005bf0a8b1457695355fb8ac404e7a )
188
+ signbit (x:: Float128 ) = signbit (reinterpret (Int128, x))
189
+ precision (:: Type{Float128} ) = 113
190
+
191
+ eps (:: Type{Float128} ) = reinterpret (Float128, 0x3f8f_0000_0000_0000_0000_0000_0000_0000 )
192
+ floatmin (:: Type{Float128} ) = reinterpret (Float128, 0x0001_0000_0000_0000_0000_0000_0000_0000 )
193
+ floatmax (:: Type{Float128} ) = reinterpret (Float128, 0x7ffe_ffff_ffff_ffff_ffff_ffff_ffff_ffff )
193
194
194
195
195
196
ldexp (x:: Float128 , n:: Cint ) =
@@ -199,10 +200,105 @@ ldexp(x::Float128, n::Integer) =
199
200
200
201
function frexp (x:: Float128 )
201
202
r = Ref {Cint} ()
202
- Float128 (ccall ((:frexpq , libquadmath), Cfloat128, (Cfloat128, Ptr{Cint}), x, r))
203
- return x , Int (r[])
203
+ y = Float128 (ccall ((:frexpq , libquadmath), Cfloat128, (Cfloat128, Ptr{Cint}), x, r))
204
+ return y , Int (r[])
204
205
end
205
206
207
+ Float128 (:: Irrational{:π} ) = reinterpret (Float128, 0x4000921fb54442d18469898cc51701b8 )
208
+ Float128 (:: Irrational{:e} ) = reinterpret (Float128, 0x40005bf0a8b1457695355fb8ac404e7a )
209
+
210
+ function BigFloat (x:: Float128 ; precision= precision (BigFloat))
211
+ if ! isfinite (x) || iszero (x)
212
+ @static if VERSION < v " 1.1"
213
+ return BigFloat (Float64 (x), precision)
214
+ else
215
+ return BigFloat (Float64 (x), precision= precision)
216
+ end
217
+ end
218
+
219
+ @static if VERSION < v " 1.1"
220
+ b = setprecision (BigFloat, max (precision,113 )) do
221
+ BigFloat ()
222
+ end
223
+ else
224
+ b = BigFloat (precision= max (precision,113 ))
225
+ end
226
+
227
+ y, k = frexp (x)
228
+ b. exp = Clong (k)
229
+ b. sign = signbit (x) ? Cint (- 1 ) : Cint (1 )
230
+ u = (reinterpret (UInt128, y) << 15 ) | 0x8000_0000_0000_0000_0000_0000_0000_0000
231
+ i = cld (precision, sizeof (Culong)* 8 )
232
+ while u != 0
233
+ w = (u >> (128 - sizeof (Culong)* 8 )) % Culong
234
+ unsafe_store! (b. d, w, i)
235
+ i -= 1
236
+ u <<= sizeof (Culong)* 8
237
+ end
238
+ # set remaining bits to zero
239
+ while i > 0
240
+ unsafe_store! (b. d, zero (Culong), i)
241
+ i -= 1
242
+ end
243
+
244
+ if precision < 113
245
+ @static if VERSION < v " 1.1"
246
+ b2 = setprecision (BigFloat, precision) do
247
+ BigFloat ()
248
+ end
249
+ ccall ((:mpfr_set , :libmpfr ), Int32, (Ref{BigFloat}, Ref{BigFloat}, Int32),
250
+ b2, b, Base. MPFR. ROUNDING_MODE[])
251
+ return b2
252
+ else
253
+ return BigFloat (b, precision= precision)
254
+ end
255
+ else
256
+ return b
257
+ end
258
+ end
259
+
260
+ function Float128 (x:: BigFloat )
261
+ if ! isfinite (x) || iszero (x)
262
+ return Float128 (Float64 (x))
263
+ end
264
+
265
+ y,k = frexp (x)
266
+ if k >= - 16381
267
+ prec = 113
268
+ elseif k >= - 16381 - 112
269
+ prec = 113 + (k + 16381 )
270
+ elseif k == - 16381 - 113 && abs (y) > 0.5
271
+ z = reinterepret (Float128, UInt128 (1 ))
272
+ else
273
+ z = reinterepret (Float128, UInt128 (0 ))
274
+ end
275
+
276
+ @static if VERSION < v " 1.1"
277
+ y = setprecision (BigFloat, prec) do
278
+ BigFloat ()
279
+ end
280
+ ccall ((:mpfr_set , :libmpfr ), Int32, (Ref{BigFloat}, Ref{BigFloat}, Int32),
281
+ y, x, Base. MPFR. ROUNDING_MODE[])
282
+ else
283
+ y = BigFloat (x, precision= prec)
284
+ end
285
+
286
+ u = zero (UInt128)
287
+ i = cld (prec, sizeof (Culong)* 8 )
288
+ j = 113
289
+ while i > 0
290
+ j -= sizeof (Culong)* 8
291
+ u |= (unsafe_load (y. d, i) % UInt128) << j
292
+ i -= 1
293
+ end
294
+ u &= significand_mask (Float128)
295
+ u |= exponent_half (Float128)
296
+ z = ldexp (reinterpret (Float128, u), y. exp)
297
+ return copysign (z,x)
298
+ end
299
+
300
+
301
+
206
302
promote_rule (:: Type{Float128} , :: Type{Float16} ) = Float128
207
303
promote_rule (:: Type{Float128} , :: Type{Float32} ) = Float128
208
304
promote_rule (:: Type{Float128} , :: Type{Float64} ) = Float128
0 commit comments