• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

JuliaLang / julia / #37527

pending completion
#37527

push

local

web-flow
make `IRShow.method_name` inferrable (#49607)

18 of 18 new or added lines in 3 files covered. (100.0%)

68710 of 81829 relevant lines covered (83.97%)

33068903.12 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

92.03
/base/math.jl
1
# This file is a part of Julia. License is MIT: https://julialang.org/license
2

3
module Math
4

5
export sin, cos, sincos, tan, sinh, cosh, tanh, asin, acos, atan,
6
       asinh, acosh, atanh, sec, csc, cot, asec, acsc, acot,
7
       sech, csch, coth, asech, acsch, acoth,
8
       sinpi, cospi, sincospi, tanpi, sinc, cosc,
9
       cosd, cotd, cscd, secd, sind, tand, sincosd,
10
       acosd, acotd, acscd, asecd, asind, atand,
11
       rad2deg, deg2rad,
12
       log, log2, log10, log1p, exponent, exp, exp2, exp10, expm1,
13
       cbrt, sqrt, fourthroot, significand,
14
       hypot, max, min, minmax, ldexp, frexp,
15
       clamp, clamp!, modf, ^, mod2pi, rem2pi,
16
       @evalpoly, evalpoly
17

18
import .Base: log, exp, sin, cos, tan, sinh, cosh, tanh, asin,
19
             acos, atan, asinh, acosh, atanh, sqrt, log2, log10,
20
             max, min, minmax, ^, exp2, muladd, rem,
21
             exp10, expm1, log1p, @constprop, @assume_effects
22

23
using .Base: sign_mask, exponent_mask, exponent_one,
24
            exponent_half, uinttype, significand_mask,
25
            significand_bits, exponent_bits, exponent_bias,
26
            exponent_max, exponent_raw_max
27

28
using Core.Intrinsics: sqrt_llvm
29

30
using .Base: IEEEFloat
31

32
@noinline function throw_complex_domainerror(f::Symbol, x)
34✔
33
    throw(DomainError(x,
34✔
34
        LazyString(f," was called with a negative real argument but will only return a complex result if called with a complex argument. Try ", f,"(Complex(x)).")))
35
end
36
@noinline function throw_complex_domainerror_neg1(f::Symbol, x)
5✔
37
    throw(DomainError(x,
5✔
38
        LazyString(f," was called with a real argument < -1 but will only return a complex result if called with a complex argument. Try ", f,"(Complex(x)).")))
39
end
40
@noinline function throw_exp_domainerror(x)
2✔
41
    throw(DomainError(x, LazyString(
2✔
42
        "Exponentiation yielding a complex result requires a ",
43
        "complex argument.\nReplace x^y with (x+0im)^y, ",
44
        "Complex(x)^y, or similar.")))
45
end
46

47
# non-type specific math functions
48

49
@assume_effects :consistent @inline function two_mul(x::Float64, y::Float64)
4,345✔
50
    if Core.Intrinsics.have_fma(Float64)
200,390,234✔
51
        xy = x*y
200,390,234✔
52
        return xy, fma(x, y, -xy)
200,390,234✔
53
    end
54
    return Base.twomul(x,y)
×
55
end
56

57
@assume_effects :consistent @inline function two_mul(x::T, y::T) where T<: Union{Float16, Float32}
4✔
58
    if Core.Intrinsics.have_fma(T)
4✔
59
        xy = x*y
4✔
60
        return xy, fma(x, y, -xy)
4✔
61
    end
62
    xy = widen(x)*y
×
63
    Txy = T(xy)
×
64
    return Txy, T(xy-Txy)
×
65
end
66

67
"""
68
    clamp(x, lo, hi)
69

70
Return `x` if `lo <= x <= hi`. If `x > hi`, return `hi`. If `x < lo`, return `lo`. Arguments
71
are promoted to a common type.
72

73
See also [`clamp!`](@ref), [`min`](@ref), [`max`](@ref).
74

75
!!! compat "Julia 1.3"
76
    `missing` as the first argument requires at least Julia 1.3.
77

78
# Examples
79
```jldoctest
80
julia> clamp.([pi, 1.0, big(10)], 2.0, 9.0)
81
3-element Vector{BigFloat}:
82
 3.141592653589793238462643383279502884197169399375105820974944592307816406286198
83
 2.0
84
 9.0
85

86
julia> clamp.([11, 8, 5], 10, 6)  # an example where lo > hi
87
3-element Vector{Int64}:
88
  6
89
  6
90
 10
91
```
92
"""
93
clamp(x::X, lo::L, hi::H) where {X,L,H} =
4,267,922✔
94
    ifelse(x > hi, convert(promote_type(X,L,H), hi),
95
           ifelse(x < lo,
96
                  convert(promote_type(X,L,H), lo),
97
                  convert(promote_type(X,L,H), x)))
98

99
"""
100
    clamp(x, T)::T
101

102
Clamp `x` between `typemin(T)` and `typemax(T)` and convert the result to type `T`.
103

104
See also [`trunc`](@ref).
105

106
# Examples
107
```jldoctest
108
julia> clamp(200, Int8)
109
127
110

111
julia> clamp(-200, Int8)
112
-128
113

114
julia> trunc(Int, 4pi^2)
115
39
116
```
117
"""
118
clamp(x, ::Type{T}) where {T<:Integer} = clamp(x, typemin(T), typemax(T)) % T
3✔
119

120

121
"""
122
    clamp!(array::AbstractArray, lo, hi)
123

124
Restrict values in `array` to the specified range, in-place.
125
See also [`clamp`](@ref).
126

127
!!! compat "Julia 1.3"
128
    `missing` entries in `array` require at least Julia 1.3.
129

130
# Examples
131
```jldoctest
132
julia> row = collect(-4:4)';
133

134
julia> clamp!(row, 0, Inf)
135
1×9 adjoint(::Vector{Int64}) with eltype Int64:
136
 0  0  0  0  0  1  2  3  4
137

138
julia> clamp.((-4:4)', 0, Inf)
139
1×9 Matrix{Float64}:
140
 0.0  0.0  0.0  0.0  0.0  1.0  2.0  3.0  4.0
141
```
142
"""
143
function clamp!(x::AbstractArray, lo, hi)
1✔
144
    @inbounds for i in eachindex(x)
2✔
145
        x[i] = clamp(x[i], lo, hi)
5✔
146
    end
9✔
147
    x
1✔
148
end
149

150
"""
151
    clamp(x::Integer, r::AbstractUnitRange)
152

153
Clamp `x` to lie within range `r`.
154

155
!!! compat "Julia 1.6"
156
     This method requires at least Julia 1.6.
157
"""
158
clamp(x::Integer, r::AbstractUnitRange{<:Integer}) = clamp(x, first(r), last(r))
46✔
159

160
"""
161
    evalpoly(x, p)
162

163
Evaluate the polynomial ``\\sum_k x^{k-1} p[k]`` for the coefficients `p[1]`, `p[2]`, ...;
164
that is, the coefficients are given in ascending order by power of `x`.
165
Loops are unrolled at compile time if the number of coefficients is statically known, i.e.
166
when `p` is a `Tuple`.
167
This function generates efficient code using Horner's method if `x` is real, or using
168
a Goertzel-like [^DK62] algorithm if `x` is complex.
169

170
[^DK62]: Donald Knuth, Art of Computer Programming, Volume 2: Seminumerical Algorithms, Sec. 4.6.4.
171

172
!!! compat "Julia 1.4"
173
    This function requires Julia 1.4 or later.
174

175
# Example
176
```jldoctest
177
julia> evalpoly(2, (1, 2, 3))
178
17
179
```
180
"""
181
function evalpoly(x, p::Tuple)
1,633,685✔
182
    if @generated
1,633,685✔
183
        N = length(p.parameters::Core.SimpleVector)
2,136✔
184
        ex = :(p[end])
2,136✔
185
        for i in N-1:-1:1
4,271✔
186
            ex = :(muladd(x, $ex, p[$i]))
5,205✔
187
        end
8,275✔
188
        ex
2,136✔
189
    else
190
        _evalpoly(x, p)
191
    end
192
end
193

194
evalpoly(x, p::AbstractVector) = _evalpoly(x, p)
2,744✔
195

196
function _evalpoly(x, p)
1,372✔
197
    Base.require_one_based_indexing(p)
1,372✔
198
    N = length(p)
1,372✔
199
    ex = p[end]
1,372✔
200
    for i in N-1:-1:1
2,744✔
201
        ex = muladd(x, ex, p[i])
2,744✔
202
    end
4,116✔
203
    ex
1,372✔
204
end
205

206
function evalpoly(z::Complex, p::Tuple)
11,029✔
207
    if @generated
11,029✔
208
        N = length(p.parameters)
13✔
209
        a = :(p[end])
13✔
210
        b = :(p[end-1])
13✔
211
        as = []
13✔
212
        for i in N-2:-1:1
13✔
213
            ai = Symbol("a", i)
22✔
214
            push!(as, :($ai = $a))
22✔
215
            a = :(muladd(r, $ai, $b))
22✔
216
            b = :(muladd(-s, $ai, p[$i]))
22✔
217
        end
22✔
218
        ai = :a0
13✔
219
        push!(as, :($ai = $a))
13✔
220
        C = Expr(:block,
13✔
221
                 :(x = real(z)),
222
                 :(y = imag(z)),
223
                 :(r = x + x),
224
                 :(s = muladd(x, x, y*y)),
225
                 as...,
226
                 :(muladd($ai, z, $b)))
227
    else
228
        _evalpoly(z, p)
229
    end
230
end
231
evalpoly(z::Complex, p::Tuple{<:Any}) = p[1]
1✔
232

233

234
evalpoly(z::Complex, p::AbstractVector) = _evalpoly(z, p)
5,489✔
235

236
function _evalpoly(z::Complex, p)
5,489✔
237
    Base.require_one_based_indexing(p)
5,489✔
238
    length(p) == 1 && return p[1]
5,489✔
239
    N = length(p)
5,488✔
240
    a = p[end]
5,488✔
241
    b = p[end-1]
5,488✔
242

243
    x = real(z)
5,488✔
244
    y = imag(z)
5,488✔
245
    r = 2x
5,488✔
246
    s = muladd(x, x, y*y)
5,488✔
247
    for i in N-2:-1:1
10,976✔
248
        ai = a
5,488✔
249
        a = muladd(r, ai, b)
5,488✔
250
        b = muladd(-s, ai, p[i])
5,488✔
251
    end
5,488✔
252
    ai = a
5,488✔
253
    muladd(ai, z, b)
5,488✔
254
end
255

256
"""
257
    @horner(x, p...)
258

259
Evaluate `p[1] + x * (p[2] + x * (....))`, i.e. a polynomial via Horner's rule.
260

261
See also [`@evalpoly`](@ref), [`evalpoly`](@ref).
262
"""
263
macro horner(x, p...)
1✔
264
     xesc, pesc = esc(x), esc.(p)
1✔
265
    :(invoke(evalpoly, Tuple{Any, Tuple}, $xesc, ($(pesc...),)))
1✔
266
end
267

268
# Evaluate p[1] + z*p[2] + z^2*p[3] + ... + z^(n-1)*p[n].  This uses
269
# Horner's method if z is real, but for complex z it uses a more
270
# efficient algorithm described in Knuth, TAOCP vol. 2, section 4.6.4,
271
# equation (3).
272

273
"""
274
    @evalpoly(z, c...)
275

276
Evaluate the polynomial ``\\sum_k z^{k-1} c[k]`` for the coefficients `c[1]`, `c[2]`, ...;
277
that is, the coefficients are given in ascending order by power of `z`.  This macro expands
278
to efficient inline code that uses either Horner's method or, for complex `z`, a more
279
efficient Goertzel-like algorithm.
280

281
See also [`evalpoly`](@ref).
282

283
# Examples
284
```jldoctest
285
julia> @evalpoly(3, 1, 0, 1)
286
10
287

288
julia> @evalpoly(2, 1, 0, 1)
289
5
290

291
julia> @evalpoly(2, 1, 1, 1)
292
7
293
```
294
"""
295
macro evalpoly(z, p...)
8✔
296
    zesc, pesc = esc(z), esc.(p)
8✔
297
    :(evalpoly($zesc, ($(pesc...),)))
8✔
298
end
299

300
# polynomial evaluation using compensated summation.
301
# much more accurate, especially when lo can be combined with other rounding errors
302
Base.@assume_effects :terminates_locally @inline function exthorner(x, p::Tuple)
1,486✔
303
    hi, lo = p[end], zero(x)
1,486✔
304
    for i in length(p)-1:-1:1
1,486✔
305
        pi = getfield(p, i) # needed to prove consistency
2,972✔
306
        prod, err = two_mul(hi,x)
2,972✔
307
        hi = pi+prod
2,972✔
308
        lo = fma(lo, x, prod - (hi - pi) + err)
2,972✔
309
    end
4,458✔
310
    return hi, lo
1,486✔
311
end
312

313
"""
314
    rad2deg(x)
315

316
Convert `x` from radians to degrees.
317

318
See also [`deg2rad`](@ref).
319

320
# Examples
321
```jldoctest
322
julia> rad2deg(pi)
323
180.0
324
```
325
"""
326
rad2deg(z::AbstractFloat) = z * (180 / oftype(z, pi))
405✔
327

328
"""
329
    deg2rad(x)
330

331
Convert `x` from degrees to radians.
332

333
See also [`rad2deg`](@ref), [`sind`](@ref), [`pi`](@ref).
334

335
# Examples
336
```jldoctest
337
julia> deg2rad(90)
338
1.5707963267948966
339
```
340
"""
341
deg2rad(z::AbstractFloat) = z * (oftype(z, pi) / 180)
506✔
342
rad2deg(z::Real) = rad2deg(float(z))
4✔
343
deg2rad(z::Real) = deg2rad(float(z))
7✔
344
rad2deg(z::Number) = (z/pi)*180
41✔
345
deg2rad(z::Number) = (z*pi)/180
23✔
346

347
log(b::T, x::T) where {T<:Number} = log(x)/log(b)
115✔
348

349
"""
350
    log(b,x)
351

352
Compute the base `b` logarithm of `x`. Throws [`DomainError`](@ref) for negative
353
[`Real`](@ref) arguments.
354

355
# Examples
356
```jldoctest; filter = r"Stacktrace:(\\n \\[[0-9]+\\].*)*"
357
julia> log(4,8)
358
1.5
359

360
julia> log(4,2)
361
0.5
362

363
julia> log(-2, 3)
364
ERROR: DomainError with -2.0:
365
log was called with a negative real argument but will only return a complex result if called with a complex argument. Try log(Complex(x)).
366
Stacktrace:
367
 [1] throw_complex_domainerror(::Symbol, ::Float64) at ./math.jl:31
368
[...]
369

370
julia> log(2, -3)
371
ERROR: DomainError with -3.0:
372
log was called with a negative real argument but will only return a complex result if called with a complex argument. Try log(Complex(x)).
373
Stacktrace:
374
 [1] throw_complex_domainerror(::Symbol, ::Float64) at ./math.jl:31
375
[...]
376
```
377

378
!!! note
379
    If `b` is a power of 2 or 10, [`log2`](@ref) or [`log10`](@ref) should be used, as these will
380
    typically be faster and more accurate. For example,
381

382
    ```jldoctest
383
    julia> log(100,1000000)
384
    2.9999999999999996
385

386
    julia> log10(1000000)/2
387
    3.0
388
    ```
389
"""
390
log(b::Number, x::Number) = log(promote(b,x)...)
30✔
391

392
# type specific math functions
393

394
const libm = Base.libm_name
395

396
# functions with no domain error
397
"""
398
    sinh(x)
399

400
Compute hyperbolic sine of `x`.
401
"""
402
sinh(x::Number)
403

404
"""
405
    cosh(x)
406

407
Compute hyperbolic cosine of `x`.
408
"""
409
cosh(x::Number)
410

411
"""
412
    tanh(x)
413

414
Compute hyperbolic tangent of `x`.
415

416
See also [`tan`](@ref), [`atanh`](@ref).
417

418
# Examples
419

420
```jldoctest
421
julia> tanh.(-3:3f0)  # Here 3f0 isa Float32
422
7-element Vector{Float32}:
423
 -0.9950548
424
 -0.9640276
425
 -0.7615942
426
  0.0
427
  0.7615942
428
  0.9640276
429
  0.9950548
430

431
julia> tan.(im .* (1:3))
432
3-element Vector{ComplexF64}:
433
 0.0 + 0.7615941559557649im
434
 0.0 + 0.9640275800758169im
435
 0.0 + 0.9950547536867306im
436
```
437
"""
438
tanh(x::Number)
439

440
"""
441
    atan(y)
442
    atan(y, x)
443

444
Compute the inverse tangent of `y` or `y/x`, respectively.
445

446
For one argument, this is the angle in radians between the positive *x*-axis and the point
447
(1, *y*), returning a value in the interval ``[-\\pi/2, \\pi/2]``.
448

449
For two arguments, this is the angle in radians between the positive *x*-axis and the
450
point (*x*, *y*), returning a value in the interval ``[-\\pi, \\pi]``. This corresponds to a
451
standard [`atan2`](https://en.wikipedia.org/wiki/Atan2) function. Note that by convention
452
`atan(0.0,x)` is defined as ``\\pi`` and `atan(-0.0,x)` is defined as ``-\\pi`` when `x < 0`.
453

454
See also [`atand`](@ref) for degrees.
455

456
# Examples
457

458
```jldoctest
459
julia> rad2deg(atan(-1/√3))
460
-30.000000000000004
461

462
julia> rad2deg(atan(-1, √3))
463
-30.000000000000004
464

465
julia> rad2deg(atan(1, -√3))
466
150.0
467
```
468
"""
469
atan(x::Number)
470

471
"""
472
    asinh(x)
473

474
Compute the inverse hyperbolic sine of `x`.
475
"""
476
asinh(x::Number)
477

478

479
# utility for converting NaN return to DomainError
480
# the branch in nan_dom_err prevents its callers from inlining, so be sure to force it
481
# until the heuristics can be improved
482
@inline nan_dom_err(out, x) = isnan(out) & !isnan(x) ? throw(DomainError(x, "NaN result for non-NaN input.")) : out
×
483

484
# functions that return NaN on non-NaN argument for domain error
485
"""
486
    sin(x)
487

488
Compute sine of `x`, where `x` is in radians.
489

490
See also [`sind`](@ref), [`sinpi`](@ref), [`sincos`](@ref), [`cis`](@ref), [`asin`](@ref).
491

492
# Examples
493
```jldoctest
494
julia> round.(sin.(range(0, 2pi, length=9)'), digits=3)
495
1×9 Matrix{Float64}:
496
 0.0  0.707  1.0  0.707  0.0  -0.707  -1.0  -0.707  -0.0
497

498
julia> sind(45)
499
0.7071067811865476
500

501
julia> sinpi(1/4)
502
0.7071067811865475
503

504
julia> round.(sincos(pi/6), digits=3)
505
(0.5, 0.866)
506

507
julia> round(cis(pi/6), digits=3)
508
0.866 + 0.5im
509

510
julia> round(exp(im*pi/6), digits=3)
511
0.866 + 0.5im
512
```
513
"""
514
sin(x::Number)
515

516
"""
517
    cos(x)
518

519
Compute cosine of `x`, where `x` is in radians.
520

521
See also [`cosd`](@ref), [`cospi`](@ref), [`sincos`](@ref), [`cis`](@ref).
522
"""
523
cos(x::Number)
524

525
"""
526
    tan(x)
527

528
Compute tangent of `x`, where `x` is in radians.
529
"""
530
tan(x::Number)
531

532
"""
533
    asin(x)
534

535
Compute the inverse sine of `x`, where the output is in radians.
536

537
See also [`asind`](@ref) for output in degrees.
538

539
# Examples
540
```jldoctest
541
julia> asin.((0, 1/2, 1))
542
(0.0, 0.5235987755982989, 1.5707963267948966)
543

544
julia> asind.((0, 1/2, 1))
545
(0.0, 30.000000000000004, 90.0)
546
```
547
"""
548
asin(x::Number)
549

550
"""
551
    acos(x)
552

553
Compute the inverse cosine of `x`, where the output is in radians
554
"""
555
acos(x::Number)
556

557
"""
558
    acosh(x)
559

560
Compute the inverse hyperbolic cosine of `x`.
561
"""
562
acosh(x::Number)
563

564
"""
565
    atanh(x)
566

567
Compute the inverse hyperbolic tangent of `x`.
568
"""
569
atanh(x::Number)
570

571
"""
572
    log(x)
573

574
Compute the natural logarithm of `x`. Throws [`DomainError`](@ref) for negative
575
[`Real`](@ref) arguments. Use complex negative arguments to obtain complex results.
576

577
See also [`ℯ`](@ref), [`log1p`](@ref), [`log2`](@ref), [`log10`](@ref).
578

579
# Examples
580
```jldoctest; filter = r"Stacktrace:(\\n \\[[0-9]+\\].*)*"
581
julia> log(2)
582
0.6931471805599453
583

584
julia> log(-3)
585
ERROR: DomainError with -3.0:
586
log was called with a negative real argument but will only return a complex result if called with a complex argument. Try log(Complex(x)).
587
Stacktrace:
588
 [1] throw_complex_domainerror(::Symbol, ::Float64) at ./math.jl:31
589
[...]
590

591
julia> log.(exp.(-1:1))
592
3-element Vector{Float64}:
593
 -1.0
594
  0.0
595
  1.0
596
```
597
"""
598
log(x::Number)
599

600
"""
601
    log2(x)
602

603
Compute the logarithm of `x` to base 2. Throws [`DomainError`](@ref) for negative
604
[`Real`](@ref) arguments.
605

606
See also: [`exp2`](@ref), [`ldexp`](@ref), [`ispow2`](@ref).
607

608
# Examples
609
```jldoctest; filter = r"Stacktrace:(\\n \\[[0-9]+\\].*)*"
610
julia> log2(4)
611
2.0
612

613
julia> log2(10)
614
3.321928094887362
615

616
julia> log2(-2)
617
ERROR: DomainError with -2.0:
618
log2 was called with a negative real argument but will only return a complex result if called with a complex argument. Try log2(Complex(x)).
619
Stacktrace:
620
 [1] throw_complex_domainerror(f::Symbol, x::Float64) at ./math.jl:31
621
[...]
622

623
julia> log2.(2.0 .^ (-1:1))
624
3-element Vector{Float64}:
625
 -1.0
626
  0.0
627
  1.0
628
```
629
"""
630
log2(x)
631

632
"""
633
    log10(x)
634

635
Compute the logarithm of `x` to base 10.
636
Throws [`DomainError`](@ref) for negative [`Real`](@ref) arguments.
637

638
# Examples
639
```jldoctest; filter = r"Stacktrace:(\\n \\[[0-9]+\\].*)*"
640
julia> log10(100)
641
2.0
642

643
julia> log10(2)
644
0.3010299956639812
645

646
julia> log10(-2)
647
ERROR: DomainError with -2.0:
648
log10 was called with a negative real argument but will only return a complex result if called with a complex argument. Try log10(Complex(x)).
649
Stacktrace:
650
 [1] throw_complex_domainerror(f::Symbol, x::Float64) at ./math.jl:31
651
[...]
652
```
653
"""
654
log10(x)
655

656
"""
657
    log1p(x)
658

659
Accurate natural logarithm of `1+x`. Throws [`DomainError`](@ref) for [`Real`](@ref)
660
arguments less than -1.
661

662
# Examples
663
```jldoctest; filter = r"Stacktrace:(\\n \\[[0-9]+\\].*)*"
664
julia> log1p(-0.5)
665
-0.6931471805599453
666

667
julia> log1p(0)
668
0.0
669

670
julia> log1p(-2)
671
ERROR: DomainError with -2.0:
672
log1p was called with a real argument < -1 but will only return a complex result if called with a complex argument. Try log1p(Complex(x)).
673
Stacktrace:
674
 [1] throw_complex_domainerror(::Symbol, ::Float64) at ./math.jl:31
675
[...]
676
```
677
"""
678
log1p(x)
679

680
@inline function sqrt(x::Union{Float32,Float64})
19,324,264✔
681
    x < zero(x) && throw_complex_domainerror(:sqrt, x)
19,324,264✔
682
    sqrt_llvm(x)
19,324,253✔
683
end
684

685
"""
686
    sqrt(x)
687

688
Return ``\\sqrt{x}``. Throws [`DomainError`](@ref) for negative [`Real`](@ref) arguments.
689
Use complex negative arguments instead. The prefix operator `√` is equivalent to `sqrt`.
690

691
See also: [`hypot`](@ref).
692

693
# Examples
694
```jldoctest; filter = r"Stacktrace:(\\n \\[[0-9]+\\].*)*"
695
julia> sqrt(big(81))
696
9.0
697

698
julia> sqrt(big(-81))
699
ERROR: DomainError with -81.0:
700
NaN result for non-NaN input.
701
Stacktrace:
702
 [1] sqrt(::BigFloat) at ./mpfr.jl:501
703
[...]
704

705
julia> sqrt(big(complex(-81)))
706
0.0 + 9.0im
707

708
julia> .√(1:4)
709
4-element Vector{Float64}:
710
 1.0
711
 1.4142135623730951
712
 1.7320508075688772
713
 2.0
714
```
715
"""
716
sqrt(x)
717

718
"""
719
    fourthroot(x)
720

721
Return the fourth root of `x` by applying `sqrt` twice successively.
722
"""
723
fourthroot(x::Number) = sqrt(sqrt(x))
4,153✔
724

725
"""
726
    hypot(x, y)
727

728
Compute the hypotenuse ``\\sqrt{|x|^2+|y|^2}`` avoiding overflow and underflow.
729

730
This code is an implementation of the algorithm described in:
731
An Improved Algorithm for `hypot(a,b)`
732
by Carlos F. Borges
733
The article is available online at arXiv at the link
734
  https://arxiv.org/abs/1904.09481
735

736
    hypot(x...)
737

738
Compute the hypotenuse ``\\sqrt{\\sum |x_i|^2}`` avoiding overflow and underflow.
739

740
See also `norm` in the [`LinearAlgebra`](@ref man-linalg) standard library.
741

742
# Examples
743
```jldoctest; filter = r"Stacktrace:(\\n \\[[0-9]+\\].*)*"
744
julia> a = Int64(10)^10;
745

746
julia> hypot(a, a)
747
1.4142135623730951e10
748

749
julia> √(a^2 + a^2) # a^2 overflows
750
ERROR: DomainError with -2.914184810805068e18:
751
sqrt was called with a negative real argument but will only return a complex result if called with a complex argument. Try sqrt(Complex(x)).
752
Stacktrace:
753
[...]
754

755
julia> hypot(3, 4im)
756
5.0
757

758
julia> hypot(-5.7)
759
5.7
760

761
julia> hypot(3, 4im, 12.0)
762
13.0
763

764
julia> using LinearAlgebra
765

766
julia> norm([a, a, a, a]) == hypot(a, a, a, a)
767
true
768
```
769
"""
770
hypot(x::Number) = abs(float(x))
4✔
771
hypot(x::Number, y::Number) = _hypot(promote(float(x), y)...)
25,648,841✔
772
hypot(x::Number, y::Number, xs::Number...) = _hypot(promote(float(x), y, xs...))
68✔
773
function _hypot(x, y)
8,816,507✔
774
    # preserves unit
775
    axu = abs(x)
8,816,507✔
776
    ayu = abs(y)
8,816,507✔
777

778
    # unitless
779
    ax = axu / oneunit(axu)
8,816,507✔
780
    ay = ayu / oneunit(ayu)
8,816,507✔
781

782
    # Return Inf if either or both inputs is Inf (Compliance with IEEE754)
783
    if isinf(ax) || isinf(ay)
17,632,511✔
784
        return typeof(axu)(Inf)
41✔
785
    end
786

787
    # Order the operands
788
    if ay > ax
8,816,466✔
789
        axu, ayu = ayu, axu
137,521✔
790
        ax, ay = ay, ax
137,521✔
791
    end
792

793
    # Widely varying operands
794
    if ay <= ax*sqrt(eps(typeof(ax))/2)  #Note: This also gets ay == 0
8,816,466✔
795
        return axu
8,532,682✔
796
    end
797

798
    # Operands do not vary widely
799
    scale = eps(typeof(ax))*sqrt(floatmin(ax))  #Rescaling constant
283,784✔
800
    if ax > sqrt(floatmax(ax)/2)
283,784✔
801
        ax = ax*scale
3✔
802
        ay = ay*scale
3✔
803
        scale = inv(scale)
3✔
804
    elseif ay < sqrt(floatmin(ax))
283,781✔
805
        ax = ax/scale
25✔
806
        ay = ay/scale
25✔
807
    else
808
        scale = oneunit(scale)
283,756✔
809
    end
810
    h = sqrt(muladd(ax, ax, ay*ay))
283,784✔
811
    # This branch is correctly rounded but requires a native hardware fma.
812
    if Core.Intrinsics.have_fma(typeof(h))
283,784✔
813
        hsquared = h*h
283,775✔
814
        axsquared = ax*ax
283,775✔
815
        h -= (fma(-ay, ay, hsquared-axsquared) + fma(h, h,-hsquared) - fma(ax, ax, -axsquared))/(2*h)
283,775✔
816
    # This branch is within one ulp of correctly rounded.
817
    else
818
        if h <= 2*ay
9✔
819
            delta = h-ay
5✔
820
            h -= muladd(delta, delta-2*(ax-ay), ax*(2*delta - ax))/(2*h)
5✔
821
        else
822
            delta = h-ax
4✔
823
            h -= muladd(delta, delta, muladd(ay, (4*delta - ay), 2*delta*(ax - 2*ay)))/(2*h)
4✔
824
        end
825
    end
826
    return h*scale*oneunit(axu)
283,784✔
827
end
828
@inline function _hypot(x::Float32, y::Float32)
8,415,142✔
829
    if isinf(x) || isinf(y)
16,829,946✔
830
        return Inf32
28✔
831
    end
832
    _x, _y = Float64(x), Float64(y)
8,415,114✔
833
    return Float32(sqrt(muladd(_x, _x, _y*_y)))
8,415,114✔
834
end
835
@inline function _hypot(x::Float16, y::Float16)
989✔
836
    if isinf(x) || isinf(y)
1,971✔
837
        return Inf16
3✔
838
    end
839
    _x, _y = Float32(x), Float32(y)
986✔
840
    return Float16(sqrt(muladd(_x, _x, _y*_y)))
1,430✔
841
end
842
_hypot(x::ComplexF16, y::ComplexF16) = Float16(_hypot(ComplexF32(x), ComplexF32(y)))
×
843

844
function _hypot(x::NTuple{N,<:Number}) where {N}
11✔
845
    maxabs = maximum(abs, x)
16✔
846
    if isnan(maxabs) && any(isinf, x)
14✔
847
        return typeof(maxabs)(Inf)
1✔
848
    elseif (iszero(maxabs) || isinf(maxabs))
19✔
849
        return maxabs
2✔
850
    else
851
        return maxabs * sqrt(sum(y -> abs2(y / maxabs), x))
32✔
852
    end
853
end
854

855
function _hypot(x::NTuple{N,<:IEEEFloat}) where {N}
57✔
856
    T = eltype(x)
57✔
857
    infT = convert(T, Inf)
57✔
858
    x = abs.(x) # doesn't change result but enables computational shortcuts
57✔
859
    # note: any() was causing this to not inline for N=3 but mapreduce() was not
860
    mapreduce(==(infT), |, x) && return infT # return Inf even if an argument is NaN
57✔
861
    maxabs = reinterpret(T, maximum(z -> reinterpret(Signed, z), x)) # for abs(::IEEEFloat) values, a ::BitInteger cast does not change the result
269✔
862
    maxabs > zero(T) || return maxabs # catch NaN before the @fastmath below, but also shortcut 0 since we can (remove if no more @fastmath below)
55✔
863
    scale,invscale = scaleinv(maxabs)
47✔
864
     # @fastmath(+) to allow reassociation (see #48129)
865
    add_fast(x, y) = Core.Intrinsics.add_float_fast(x, y) # @fastmath is not available during bootstrap
206✔
866
    return scale * sqrt(mapreduce(y -> abs2(y * invscale), add_fast, x))
253✔
867
end
868

869
atan(y::Real, x::Real) = atan(promote(float(y),float(x))...)
10✔
870
atan(y::T, x::T) where {T<:AbstractFloat} = Base.no_op_err("atan", T)
×
871

872
_isless(x::T, y::T) where {T<:AbstractFloat} = (x < y) || (signbit(x) > signbit(y))
2,894,264✔
873
min(x::T, y::T) where {T<:AbstractFloat} = isnan(x) || ~isnan(y) && _isless(x, y) ? x : y
2,439,783✔
874
max(x::T, y::T) where {T<:AbstractFloat} = isnan(x) || ~isnan(y) && _isless(y, x) ? x : y
2,432,284✔
875
minmax(x::T, y::T) where {T<:AbstractFloat} = min(x, y), max(x, y)
19✔
876

877
_isless(x::Float16, y::Float16) = signbit(widen(x) - widen(y))
2,295,642✔
878

879
const has_native_fminmax = Sys.ARCH === :aarch64
880
@static if has_native_fminmax
881
    @eval begin
882
        Base.@assume_effects :total @inline llvm_min(x::Float64, y::Float64) = ccall("llvm.minimum.f64", llvmcall, Float64, (Float64, Float64), x, y)
×
883
        Base.@assume_effects :total @inline llvm_min(x::Float32, y::Float32) = ccall("llvm.minimum.f32", llvmcall, Float32, (Float32, Float32), x, y)
×
884
        Base.@assume_effects :total @inline llvm_max(x::Float64, y::Float64) = ccall("llvm.maximum.f64", llvmcall, Float64, (Float64, Float64), x, y)
×
885
        Base.@assume_effects :total @inline llvm_max(x::Float32, y::Float32) = ccall("llvm.maximum.f32", llvmcall, Float32, (Float32, Float32), x, y)
×
886
    end
887
end
888

889
function min(x::T, y::T) where {T<:Union{Float32,Float64}}
3,964,590✔
890
    @static if has_native_fminmax
×
891
        return llvm_min(x,y)
892
    end
893
    diff = x - y
3,964,873✔
894
    argmin = ifelse(signbit(diff), x, y)
3,964,880✔
895
    anynan = isnan(x)|isnan(y)
3,964,874✔
896
    return ifelse(anynan, diff, argmin)
3,964,865✔
897
end
898

899
function max(x::T, y::T) where {T<:Union{Float32,Float64}}
35,666,634✔
900
    @static if has_native_fminmax
×
901
        return llvm_max(x,y)
902
    end
903
    diff = x - y
35,666,633✔
904
    argmax = ifelse(signbit(diff), y, x)
35,666,633✔
905
    anynan = isnan(x)|isnan(y)
35,666,634✔
906
    return ifelse(anynan, diff, argmax)
35,666,630✔
907
end
908

909
function minmax(x::T, y::T) where {T<:Union{Float32,Float64}}
38✔
910
    @static if has_native_fminmax
×
911
        return llvm_min(x, y), llvm_max(x, y)
912
    end
913
    diff = x - y
38✔
914
    sdiff = signbit(diff)
38✔
915
    min, max = ifelse(sdiff, x, y), ifelse(sdiff, y, x)
38✔
916
    anynan = isnan(x)|isnan(y)
38✔
917
    return ifelse(anynan, diff, min), ifelse(anynan, diff, max)
38✔
918
end
919

920
"""
921
    ldexp(x, n)
922

923
Compute ``x \\times 2^n``.
924

925
# Examples
926
```jldoctest
927
julia> ldexp(5., 2)
928
20.0
929
```
930
"""
931
function ldexp(x::T, e::Integer) where T<:IEEEFloat
2,518,449✔
932
    xu = reinterpret(Unsigned, x)
2,679,352✔
933
    xs = xu & ~sign_mask(T)
2,679,352✔
934
    xs >= exponent_mask(T) && return x # NaN or Inf
3,000,005✔
935
    k = (xs >> significand_bits(T)) % Int
2,679,027✔
936
    if k == 0 # x is subnormal
2,999,680✔
937
        xs == 0 && return x # +-0
7,208✔
938
        m = leading_zeros(xs) - exponent_bits(T)
82✔
939
        ys = xs << unsigned(m)
82✔
940
        xu = ys | (xu & sign_mask(T))
82✔
941
        k = 1 - m
82✔
942
        # underflow, otherwise may have integer underflow in the following n + k
943
        e < -50000 && return flipsign(T(0.0), x)
82✔
944
    end
945
    # For cases where e of an Integer larger than Int make sure we properly
946
    # overflow/underflow; this is optimized away otherwise.
947
    if e > typemax(Int)
2,992,548✔
948
        return flipsign(T(Inf), x)
12✔
949
    elseif e < typemin(Int)
2,992,536✔
950
        return flipsign(T(0.0), x)
8✔
951
    end
952
    n = e % Int
2,483,648✔
953
    k += n
2,992,528✔
954
    # overflow, if k is larger than maximum possible exponent
955
    if k >= exponent_raw_max(T)
2,992,528✔
956
        return flipsign(T(Inf), x)
89,141✔
957
    end
958
    if k > 0 # normal case
2,903,387✔
959
        xu = (xu & ~exponent_mask(T)) | (rem(k, uinttype(T)) << significand_bits(T))
2,872,608✔
960
        return reinterpret(T, xu)
2,872,608✔
961
    else # subnormal case
962
        if k <= -significand_bits(T) # underflow
30,779✔
963
            # overflow, for the case of integer overflow in n + k
964
            e > 50000 && return flipsign(T(Inf), x)
21,113✔
965
            return flipsign(T(0.0), x)
21,109✔
966
        end
967
        k += significand_bits(T)
9,666✔
968
        # z = T(2.0) ^ (-significand_bits(T))
969
        z = reinterpret(T, rem(exponent_bias(T)-significand_bits(T), uinttype(T)) << significand_bits(T))
6,209✔
970
        xu = (xu & ~exponent_mask(T)) | (rem(k, uinttype(T)) << significand_bits(T))
9,666✔
971
        return z*reinterpret(T, xu)
9,666✔
972
    end
973
end
974
ldexp(x::Float16, q::Integer) = Float16(ldexp(Float32(x), q))
2,793,621✔
975

976
"""
977
    exponent(x) -> Int
978

979
Returns the largest integer `y` such that `2^y ≤ abs(x)`.
980
For a normalized floating-point number `x`, this corresponds to the exponent of `x`.
981

982
# Examples
983
```jldoctest
984
julia> exponent(8)
985
3
986

987
julia> exponent(64//1)
988
6
989

990
julia> exponent(6.5)
991
2
992

993
julia> exponent(16.0)
994
4
995

996
julia> exponent(3.142e-4)
997
-12
998
```
999
"""
1000
function exponent(x::T) where T<:IEEEFloat
482,985✔
1001
    @noinline throw1(x) = throw(DomainError(x, "Cannot be NaN or Inf."))
3,643,363✔
1002
    @noinline throw2(x) = throw(DomainError(x, "Cannot be ±0.0."))
3,643,366✔
1003
    xs = reinterpret(Unsigned, x) & ~sign_mask(T)
3,643,360✔
1004
    xs >= exponent_mask(T) && throw1(x)
3,643,360✔
1005
    k = Int(xs >> significand_bits(T))
3,643,357✔
1006
    if k == 0 # x is subnormal
3,643,357✔
1007
        xs == 0 && throw2(x)
19,701✔
1008
        m = leading_zeros(xs) - exponent_bits(T)
19,695✔
1009
        k = 1 - m
19,695✔
1010
    end
1011
    return k - exponent_bias(T)
3,643,351✔
1012
end
1013

1014
# Like exponent, but assumes the nothrow precondition. For
1015
# internal use only. Could be written as
1016
# @assume_effects :nothrow exponent()
1017
# but currently this form is easier on the compiler.
1018
function _exponent_finite_nonzero(x::T) where T<:IEEEFloat
×
1019
    # @precond :nothrow !isnan(x) && !isinf(x) && !iszero(x)
1020
    xs = reinterpret(Unsigned, x) & ~sign_mask(T)
138,590✔
1021
    k = rem(xs >> significand_bits(T), Int)
138,590✔
1022
    if k == 0 # x is subnormal
138,590✔
1023
        m = leading_zeros(xs) - exponent_bits(T)
276✔
1024
        k = 1 - m
276✔
1025
    end
1026
    return k - exponent_bias(T)
138,590✔
1027
end
1028

1029
"""
1030
    significand(x)
1031

1032
Extract the significand (a.k.a. mantissa) of a floating-point number. If `x` is
1033
a non-zero finite number, then the result will be a number of the same type and
1034
sign as `x`, and whose absolute value is on the interval ``[1,2)``. Otherwise
1035
`x` is returned.
1036

1037
# Examples
1038
```jldoctest
1039
julia> significand(15.2)
1040
1.9
1041

1042
julia> significand(-15.2)
1043
-1.9
1044

1045
julia> significand(-15.2) * 2^3
1046
-15.2
1047

1048
julia> significand(-Inf), significand(Inf), significand(NaN)
1049
(-Inf, Inf, NaN)
1050
```
1051
"""
1052
function significand(x::T) where T<:IEEEFloat
51✔
1053
    xu = reinterpret(Unsigned, x)
2,839,773✔
1054
    xs = xu & ~sign_mask(T)
2,839,773✔
1055
    xs >= exponent_mask(T) && return x # NaN or Inf
2,839,773✔
1056
    if xs <= (~exponent_mask(T) & ~sign_mask(T)) # x is subnormal
2,839,770✔
1057
        xs == 0 && return x # +-0
19,700✔
1058
        m = unsigned(leading_zeros(xs) - exponent_bits(T))
19,694✔
1059
        xs <<= m
19,694✔
1060
        xu = xs | (xu & sign_mask(T))
19,694✔
1061
    end
1062
    xu = (xu & ~exponent_mask(T)) | exponent_one(T)
2,839,764✔
1063
    return reinterpret(T, xu)
2,839,764✔
1064
end
1065

1066
"""
1067
    frexp(val)
1068

1069
Return `(x,exp)` such that `x` has a magnitude in the interval ``[1/2, 1)`` or 0,
1070
and `val` is equal to ``x \\times 2^{exp}``.
1071
# Examples
1072
```jldoctest
1073
julia> frexp(12.8)
1074
(0.8, 4)
1075
```
1076
"""
1077
function frexp(x::T) where T<:IEEEFloat
1,999,608✔
1078
    xu = reinterpret(Unsigned, x)
1,999,608✔
1079
    xs = xu & ~sign_mask(T)
1,999,608✔
1080
    xs >= exponent_mask(T) && return x, 0 # NaN or Inf
1,999,608✔
1081
    k = Int(xs >> significand_bits(T))
1,999,545✔
1082
    if k == 0 # x is subnormal
1,999,545✔
1083
        xs == 0 && return x, 0 # +-0
206✔
1084
        m = leading_zeros(xs) - exponent_bits(T)
36✔
1085
        xs <<= unsigned(m)
36✔
1086
        xu = xs | (xu & sign_mask(T))
36✔
1087
        k = 1 - m
36✔
1088
    end
1089
    k -= (exponent_bias(T) - 1)
1,999,375✔
1090
    xu = (xu & ~exponent_mask(T)) | exponent_half(T)
1,999,375✔
1091
    return reinterpret(T, xu), k
1,999,375✔
1092
end
1093

1094
"""
1095
    $(@__MODULE__).scaleinv(x)
1096

1097
Compute `(scale, invscale)` where `scale` and `invscale` are non-subnormal
1098
(https://en.wikipedia.org/wiki/Subnormal_number) finite powers of two such that
1099
`scale * invscale == 1` and `scale` is roughly on the order of `abs(x)`.
1100
Inf, NaN, and zero inputs also result in finite nonzero outputs.
1101
These values are useful to scale computations to prevent overflow and underflow
1102
without round-off errors or division.
1103

1104
UNSTABLE DETAIL: For `x isa IEEEFLoat`, `scale` is chosen to be the
1105
`prevpow(2,abs(x))` when possible, but is never less than floatmin(x) or greater
1106
than inv(floatmin(x)). `Inf` and `NaN` resolve to `inv(floatmin(x))`. This
1107
behavior is subject to change.
1108

1109
# Examples
1110
```jldoctest
1111
julia> $(@__MODULE__).scaleinv(7.5)
1112
(4.0, 0.25)
1113
```
1114
"""
1115
function scaleinv(x::T) where T<:IEEEFloat
47✔
1116
    # by removing the sign and significand and restricting values to a limited range,
1117
    # we can invert a number using bit-twiddling instead of division
1118
    U = uinttype(T)
47✔
1119
    umin = reinterpret(U, floatmin(T))
47✔
1120
    umax = reinterpret(U, inv(floatmin(T)))
47✔
1121
    emask = exponent_mask(T) # used to strip sign and significand
47✔
1122
    u = clamp(reinterpret(U, x) & emask, umin, umax)
47✔
1123
    scale = reinterpret(T, u)
47✔
1124
    invscale = reinterpret(T, umin + umax - u) # inv(scale)
47✔
1125
    return scale, invscale
47✔
1126
end
1127

1128
# NOTE: This `rem` method is adapted from the msun `remainder` and `remainderf`
1129
# functions, which are under the following license:
1130
#
1131
# Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
1132
#
1133
# Developed at SunSoft, a Sun Microsystems, Inc. business.
1134
# Permission to use, copy, modify, and distribute this
1135
# software is freely granted, provided that this notice
1136
# is preserved.
1137
function rem(x::T, p::T, ::RoundingMode{:Nearest}) where T<:IEEEFloat
139✔
1138
    (iszero(p) || !isfinite(x) || isnan(p)) && return T(NaN)
139✔
1139
    x == p && return copysign(zero(T), x)
130✔
1140
    oldx = x
120✔
1141
    x = abs(rem(x, 2p))  # 2p may overflow but that's okay
120✔
1142
    p = abs(p)
120✔
1143
    if p < 2 * floatmin(T)  # Check whether dividing p by 2 will underflow
120✔
1144
        if 2x > p
×
1145
            x -= p
×
1146
            if 2x >= p
×
1147
                x -= p
×
1148
            end
1149
        end
1150
    else
1151
        p_half = p / 2
120✔
1152
        if x > p_half
120✔
1153
            x -= p
108✔
1154
            if x >= p_half
108✔
1155
                x -= p
×
1156
            end
1157
        end
1158
    end
1159
    return flipsign(x, oldx)
120✔
1160
end
1161

1162

1163
"""
1164
    modf(x)
1165

1166
Return a tuple `(fpart, ipart)` of the fractional and integral parts of a number. Both parts
1167
have the same sign as the argument.
1168

1169
# Examples
1170
```jldoctest
1171
julia> modf(3.5)
1172
(0.5, 3.0)
1173

1174
julia> modf(-3.5)
1175
(-0.5, -3.0)
1176
```
1177
"""
1178
modf(x) = isinf(x) ? (flipsign(zero(x), x), x) : (rem(x, one(x)), trunc(x))
×
1179

1180
function modf(x::T) where T<:IEEEFloat
21✔
1181
    isinf(x) && return (copysign(zero(T), x), x)
21✔
1182
    ix = trunc(x)
15✔
1183
    rx = copysign(x - ix, x)
15✔
1184
    return (rx, ix)
15✔
1185
end
1186

1187
# @constprop aggressive to help the compiler see the switch between the integer and float
1188
# variants for callers with constant `y`
1189
@constprop :aggressive function ^(x::Float64, y::Float64)
246,037✔
1190
    xu = reinterpret(UInt64, x)
246,037✔
1191
    xu == reinterpret(UInt64, 1.0) && return 1.0
246,037✔
1192
    # Exponents greater than this will always overflow or underflow.
1193
    # Note that NaN can pass through this, but that will end up fine.
1194
    if !(abs(y)<0x1.8p62)
242,908✔
1195
        isnan(y) && return y
54✔
1196
        y = sign(y)*0x1.8p62
35✔
1197
    end
1198
    yint = unsafe_trunc(Int64, y) # This is actually safe since julia freezes the result
242,889✔
1199
    y == yint && return @noinline x^yint
242,889✔
1200
    2*xu==0 && return abs(y)*Inf*(!(y>0)) # if x==0
173,669✔
1201
    x<0 && throw_exp_domainerror(x) # |y| is small enough that y isn't an integer
172,787✔
1202
    !isfinite(x) && return x*(y>0 || isnan(x))           # x is inf or NaN
172,785✔
1203
    if xu < (UInt64(1)<<52) # x is subnormal
172,750✔
1204
        xu = reinterpret(UInt64, x * 0x1p52) # normalize x
16,384✔
1205
        xu &= ~sign_mask(Float64)
16,384✔
1206
        xu -= UInt64(52) << 52 # mess with the exponent
16,384✔
1207
    end
1208
    return pow_body(xu, y)
172,750✔
1209
end
1210

1211
@inline function pow_body(xu::UInt64, y::Float64)
×
1212
    logxhi,logxlo = Base.Math._log_ext(xu)
172,750✔
1213
    xyhi, xylo = two_mul(logxhi,y)
172,750✔
1214
    xylo = muladd(logxlo, y, xylo)
172,750✔
1215
    hi = xyhi+xylo
172,750✔
1216
    return Base.Math.exp_impl(hi, xylo-(hi-xyhi), Val(:ℯ))
177,183✔
1217
end
1218

1219
@constprop :aggressive function ^(x::T, y::T) where T <: Union{Float16, Float32}
246,034✔
1220
    x == 1 && return one(T)
246,034✔
1221
    # Exponents greater than this will always overflow or underflow.
1222
    # Note that NaN can pass through this, but that will end up fine.
1223
    max_exp = T == Float16 ? T(3<<14) : T(0x1.Ap30)
245,951✔
1224
    if !(abs(y)<max_exp)
245,951✔
1225
        isnan(y) && return y
72✔
1226
        y = sign(y)*max_exp
38✔
1227
    end
1228
    yint = unsafe_trunc(Int32, y) # This is actually safe since julia freezes the result
245,917✔
1229
    y == yint && return x^yint
245,917✔
1230
    x < 0 && throw_exp_domainerror(x)
234,533✔
1231
    !isfinite(x) && return x*(y>0 || isnan(x))
234,533✔
1232
    x==0 && return abs(y)*T(Inf)*(!(y>0))
234,531✔
1233
    return pow_body(x, y)
234,459✔
1234
end
1235

1236
@inline function pow_body(x::T, y::T) where T <: Union{Float16, Float32}
234,459✔
1237
    return T(exp2(log2(abs(widen(x))) * y))
234,459✔
1238
end
1239

1240
# compensated power by squaring
1241
@constprop :aggressive @inline function ^(x::Float64, n::Integer)
600,080,914✔
1242
    n == 0 && return one(x)
600,110,085✔
1243
    return pow_body(x, n)
600,107,947✔
1244
end
1245

1246
@assume_effects :terminates_locally @noinline function pow_body(x::Float64, n::Integer)
600,107,959✔
1247
    y = 1.0
11✔
1248
    xnlo = ynlo = 0.0
11✔
1249
    n == 3 && return x*x*x # keep compatibility with literal_pow
600,107,959✔
1250
    if n < 0
400,081,855✔
1251
        rx = inv(x)
200,039,930✔
1252
        n==-2 && return rx*rx #keep compatibility with literal_pow
200,039,930✔
1253
        isfinite(x) && (xnlo = -fma(x, rx, -1.) * rx)
200,021,710✔
1254
        x = rx
200,021,710✔
1255
        n = -n
200,021,710✔
1256
    end
1257
    while n > 1
600,091,812✔
1258
        if n&1 > 0
200,028,177✔
1259
            err = muladd(y, xnlo, x*ynlo)
12,206✔
1260
            y, ynlo = two_mul(x,y)
12,206✔
1261
            ynlo += err
12,206✔
1262
        end
1263
        err = x*2*xnlo
200,028,177✔
1264
        x, xnlo = two_mul(x, x)
200,028,177✔
1265
        xnlo += err
200,028,177✔
1266
        n >>>= 1
200,028,177✔
1267
    end
200,028,177✔
1268
    err = muladd(y, xnlo, x*ynlo)
400,063,635✔
1269
    return ifelse(isfinite(x) & isfinite(err), muladd(x, y, err), x*y)
400,063,635✔
1270
end
1271

1272
function ^(x::Float32, n::Integer)
600,012,936✔
1273
    n == -2 && return (i=inv(x); i*i)
600,012,940✔
1274
    n == 3 && return x*x*x #keep compatibility with literal_pow
600,012,932✔
1275
    n < 0 && return Float32(Base.power_by_squaring(inv(Float64(x)),-n))
400,012,864✔
1276
    Float32(Base.power_by_squaring(Float64(x),n))
200,008,156✔
1277
end
1278
@inline ^(x::Float16, y::Integer) = Float16(Float32(x) ^ y)
5,828✔
1279
@inline literal_pow(::typeof(^), x::Float16, ::Val{p}) where {p} = Float16(literal_pow(^,Float32(x),Val(p)))
×
1280

1281
## rem2pi-related calculations ##
1282

1283
function add22condh(xh::Float64, xl::Float64, yh::Float64, yl::Float64)
54✔
1284
    # This algorithm, due to Dekker, computes the sum of two
1285
    # double-double numbers and returns the high double. References:
1286
    # [1] http://www.digizeitschriften.de/en/dms/img/?PID=GDZPPN001170007
1287
    # [2] https://doi.org/10.1007/BF01397083
1288
    r = xh+yh
54✔
1289
    s = (abs(xh) > abs(yh)) ? (xh-r+yh+yl+xl) : (yh-r+xh+xl+yl)
108✔
1290
    zh = r+s
54✔
1291
    return zh
54✔
1292
end
1293

1294
# multiples of pi/2, as double-double (ie with "tail")
1295
const pi1o2_h  = 1.5707963267948966     # convert(Float64, pi * BigFloat(1/2))
1296
const pi1o2_l  = 6.123233995736766e-17  # convert(Float64, pi * BigFloat(1/2) - pi1o2_h)
1297

1298
const pi2o2_h  = 3.141592653589793      # convert(Float64, pi * BigFloat(1))
1299
const pi2o2_l  = 1.2246467991473532e-16 # convert(Float64, pi * BigFloat(1) - pi2o2_h)
1300

1301
const pi3o2_h  = 4.71238898038469       # convert(Float64, pi * BigFloat(3/2))
1302
const pi3o2_l  = 1.8369701987210297e-16 # convert(Float64, pi * BigFloat(3/2) - pi3o2_h)
1303

1304
const pi4o2_h  = 6.283185307179586      # convert(Float64, pi * BigFloat(2))
1305
const pi4o2_l  = 2.4492935982947064e-16 # convert(Float64, pi * BigFloat(2) - pi4o2_h)
1306

1307
"""
1308
    rem2pi(x, r::RoundingMode)
1309

1310
Compute the remainder of `x` after integer division by `2π`, with the quotient rounded
1311
according to the rounding mode `r`. In other words, the quantity
1312

1313
    x - 2π*round(x/(2π),r)
1314

1315
without any intermediate rounding. This internally uses a high precision approximation of
1316
2π, and so will give a more accurate result than `rem(x,2π,r)`
1317

1318
- if `r == RoundNearest`, then the result is in the interval ``[-π, π]``. This will generally
1319
  be the most accurate result. See also [`RoundNearest`](@ref).
1320

1321
- if `r == RoundToZero`, then the result is in the interval ``[0, 2π]`` if `x` is positive,.
1322
  or ``[-2π, 0]`` otherwise. See also [`RoundToZero`](@ref).
1323

1324
- if `r == RoundDown`, then the result is in the interval ``[0, 2π]``.
1325
  See also [`RoundDown`](@ref).
1326
- if `r == RoundUp`, then the result is in the interval ``[-2π, 0]``.
1327
  See also [`RoundUp`](@ref).
1328

1329
# Examples
1330
```jldoctest
1331
julia> rem2pi(7pi/4, RoundNearest)
1332
-0.7853981633974485
1333

1334
julia> rem2pi(7pi/4, RoundDown)
1335
5.497787143782138
1336
```
1337
"""
1338
function rem2pi end
1339
function rem2pi(x::Float64, ::RoundingMode{:Nearest})
69✔
1340
    isnan(x) && return x
69✔
1341
    isinf(x) && return NaN
42✔
1342

1343
    abs(x) < pi && return x
30✔
1344

1345
    n,y = rem_pio2_kernel(x)
18✔
1346

1347
    if iseven(n)
18✔
1348
        if n & 2 == 2 # n % 4 == 2: add/subtract pi
6✔
1349
            if y.hi <= 0
×
1350
                return add22condh(y.hi,y.lo,pi2o2_h,pi2o2_l)
×
1351
            else
1352
                return add22condh(y.hi,y.lo,-pi2o2_h,-pi2o2_l)
×
1353
            end
1354
        else          # n % 4 == 0: add 0
1355
            return y.hi+y.lo
6✔
1356
        end
1357
    else
1358
        if n & 2 == 2 # n % 4 == 3: subtract pi/2
12✔
1359
            return add22condh(y.hi,y.lo,-pi1o2_h,-pi1o2_l)
6✔
1360
        else          # n % 4 == 1: add pi/2
1361
            return add22condh(y.hi,y.lo,pi1o2_h,pi1o2_l)
6✔
1362
        end
1363
    end
1364
end
1365
function rem2pi(x::Float64, ::RoundingMode{:ToZero})
69✔
1366
    isnan(x) && return x
69✔
1367
    isinf(x) && return NaN
42✔
1368

1369
    ax = abs(x)
30✔
1370
    ax <= 2*Float64(pi,RoundDown) && return x
30✔
1371

1372
    n,y = rem_pio2_kernel(ax)
12✔
1373

1374
    if iseven(n)
12✔
1375
        if n & 2 == 2 # n % 4 == 2: add pi
6✔
1376
            z = add22condh(y.hi,y.lo,pi2o2_h,pi2o2_l)
×
1377
        else          # n % 4 == 0: add 0 or 2pi
1378
            if y.hi > 0
6✔
1379
                z = y.hi+y.lo
6✔
1380
            else      # negative: add 2pi
1381
                z = add22condh(y.hi,y.lo,pi4o2_h,pi4o2_l)
6✔
1382
            end
1383
        end
1384
    else
1385
        if n & 2 == 2 # n % 4 == 3: add 3pi/2
6✔
1386
            z = add22condh(y.hi,y.lo,pi3o2_h,pi3o2_l)
×
1387
        else          # n % 4 == 1: add pi/2
1388
            z = add22condh(y.hi,y.lo,pi1o2_h,pi1o2_l)
6✔
1389
        end
1390
    end
1391
    copysign(z,x)
12✔
1392
end
1393
function rem2pi(x::Float64, ::RoundingMode{:Down})
69✔
1394
    isnan(x) && return x
69✔
1395
    isinf(x) && return NaN
42✔
1396

1397
    if x < pi4o2_h
30✔
1398
        if x >= 0
24✔
1399
            return x
12✔
1400
        elseif x > -pi4o2_h
12✔
1401
            return add22condh(x,0.0,pi4o2_h,pi4o2_l)
6✔
1402
        end
1403
    end
1404

1405
    n,y = rem_pio2_kernel(x)
12✔
1406

1407
    if iseven(n)
12✔
1408
        if n & 2 == 2 # n % 4 == 2: add pi
6✔
1409
            return add22condh(y.hi,y.lo,pi2o2_h,pi2o2_l)
×
1410
        else          # n % 4 == 0: add 0 or 2pi
1411
            if y.hi > 0
6✔
1412
                return y.hi+y.lo
3✔
1413
            else      # negative: add 2pi
1414
                return add22condh(y.hi,y.lo,pi4o2_h,pi4o2_l)
3✔
1415
            end
1416
        end
1417
    else
1418
        if n & 2 == 2 # n % 4 == 3: add 3pi/2
6✔
1419
            return add22condh(y.hi,y.lo,pi3o2_h,pi3o2_l)
3✔
1420
        else          # n % 4 == 1: add pi/2
1421
            return add22condh(y.hi,y.lo,pi1o2_h,pi1o2_l)
3✔
1422
        end
1423
    end
1424
end
1425
function rem2pi(x::Float64, ::RoundingMode{:Up})
69✔
1426
    isnan(x) && return x
69✔
1427
    isinf(x) && return NaN
42✔
1428

1429
    if x > -pi4o2_h
30✔
1430
        if x <= 0
24✔
1431
            return x
6✔
1432
        elseif x < pi4o2_h
18✔
1433
            return add22condh(x,0.0,-pi4o2_h,-pi4o2_l)
12✔
1434
        end
1435
    end
1436

1437
    n,y = rem_pio2_kernel(x)
12✔
1438

1439
    if iseven(n)
12✔
1440
        if n & 2 == 2 # n % 4 == 2: sub pi
6✔
1441
            return add22condh(y.hi,y.lo,-pi2o2_h,-pi2o2_l)
×
1442
        else          # n % 4 == 0: sub 0 or 2pi
1443
            if y.hi < 0
6✔
1444
                return y.hi+y.lo
3✔
1445
            else      # positive: sub 2pi
1446
                return add22condh(y.hi,y.lo,-pi4o2_h,-pi4o2_l)
3✔
1447
            end
1448
        end
1449
    else
1450
        if n & 2 == 2 # n % 4 == 3: sub pi/2
6✔
1451
            return add22condh(y.hi,y.lo,-pi1o2_h,-pi1o2_l)
3✔
1452
        else          # n % 4 == 1: sub 3pi/2
1453
            return add22condh(y.hi,y.lo,-pi3o2_h,-pi3o2_l)
3✔
1454
        end
1455
    end
1456
end
1457

1458
rem2pi(x::Float32, r::RoundingMode) = Float32(rem2pi(Float64(x), r))
92✔
1459
rem2pi(x::Float16, r::RoundingMode) = Float16(rem2pi(Float64(x), r))
92✔
1460
rem2pi(x::Int32, r::RoundingMode) = rem2pi(Float64(x), r)
×
1461
function rem2pi(x::Int64, r::RoundingMode)
×
1462
    fx = Float64(x)
×
1463
    fx == x || throw(ArgumentError("Int64 argument to rem2pi is too large: $x"))
×
1464
    rem2pi(fx, r)
×
1465
end
1466

1467
"""
1468
    mod2pi(x)
1469

1470
Modulus after division by `2π`, returning in the range ``[0,2π)``.
1471

1472
This function computes a floating point representation of the modulus after division by
1473
numerically exact `2π`, and is therefore not exactly the same as `mod(x,2π)`, which would
1474
compute the modulus of `x` relative to division by the floating-point number `2π`.
1475

1476
!!! note
1477
    Depending on the format of the input value, the closest representable value to 2π may
1478
    be less than 2π. For example, the expression `mod2pi(2π)` will not return `0`, because
1479
    the intermediate value of `2*π` is a `Float64` and `2*Float64(π) < 2*big(π)`. See
1480
    [`rem2pi`](@ref) for more refined control of this behavior.
1481

1482
# Examples
1483
```jldoctest
1484
julia> mod2pi(9*pi/4)
1485
0.7853981633974481
1486
```
1487
"""
1488
mod2pi(x) = rem2pi(x,RoundDown)
×
1489

1490
# generic fallback; for number types, promotion.jl does promotion
1491

1492
"""
1493
    muladd(x, y, z)
1494

1495
Combined multiply-add: computes `x*y+z`, but allowing the add and multiply to be merged
1496
with each other or with surrounding operations for performance.
1497
For example, this may be implemented as an [`fma`](@ref) if the hardware supports it
1498
efficiently.
1499
The result can be different on different machines and can also be different on the same machine
1500
due to constant propagation or other optimizations.
1501
See [`fma`](@ref).
1502

1503
# Examples
1504
```jldoctest
1505
julia> muladd(3, 2, 1)
1506
7
1507

1508
julia> 3 * 2 + 1
1509
7
1510
```
1511
"""
1512
muladd(x,y,z) = x*y+z
4✔
1513

1514

1515
# helper functions for Libm functionality
1516

1517
"""
1518
    highword(x)
1519

1520
Return the high word of `x` as a `UInt32`.
1521
"""
1522
@inline highword(x::Float64) = highword(reinterpret(UInt64, x))
20,596✔
1523
@inline highword(x::UInt64)  = (x >>> 32) % UInt32
154,821✔
1524
@inline highword(x::Float32) = reinterpret(UInt32, x)
5,633✔
1525

1526
@inline fromhighword(::Type{Float64}, u::UInt32) = reinterpret(Float64, UInt64(u) << 32)
2,828✔
1527
@inline fromhighword(::Type{Float32}, u::UInt32) = reinterpret(Float32, u)
2,276✔
1528

1529

1530
"""
1531
    poshighword(x)
1532

1533
Return positive part of the high word of `x` as a `UInt32`.
1534
"""
1535
@inline poshighword(x::Float64) = poshighword(reinterpret(UInt64, x))
134,225✔
1536
@inline poshighword(x::UInt64)  = highword(x) & 0x7fffffff
134,225✔
1537
@inline poshighword(x::Float32) = highword(x) & 0x7fffffff
1,078✔
1538

1539
# More special functions
1540
include("special/cbrt.jl")
1541
include("special/exp.jl")
1542
include("special/hyperbolic.jl")
1543
include("special/trig.jl")
1544
include("special/rem_pio2.jl")
1545
include("special/log.jl")
1546

1547

1548
# Float16 definitions
1549

1550
for func in (:sin,:cos,:tan,:asin,:acos,:atan,:cosh,:tanh,:asinh,:acosh,
1551
             :atanh,:log,:log2,:log10,:sqrt,:fourthroot,:log1p)
1552
    @eval begin
1553
        $func(a::Float16) = Float16($func(Float32(a)))
202,255✔
1554
        $func(a::ComplexF16) = ComplexF16($func(ComplexF32(a)))
1✔
1555
    end
1556
end
1557

1558
for func in (:exp,:exp2,:exp10,:sinh)
1559
     @eval $func(a::ComplexF16) = ComplexF16($func(ComplexF32(a)))
×
1560
end
1561

1562

1563
atan(a::Float16,b::Float16) = Float16(atan(Float32(a),Float32(b)))
7✔
1564
sincos(a::Float16) = Float16.(sincos(Float32(a)))
4✔
1565

1566
for f in (:sin, :cos, :tan, :asin, :atan, :acos,
1567
          :sinh, :cosh, :tanh, :asinh, :acosh, :atanh,
1568
          :exp, :exp2, :exp10, :expm1, :log, :log2, :log10, :log1p,
1569
          :exponent, :sqrt, :cbrt)
1570
    @eval function ($f)(x::Real)
83,179✔
1571
        xf = float(x)
87,887✔
1572
        x === xf && throw(MethodError($f, (x,)))
82,159✔
1573
        return ($f)(xf)
86,869✔
1574
    end
1575
    @eval $(f)(::Missing) = missing
39✔
1576
end
1577

1578
for f in (:atan, :hypot, :log)
1579
    @eval $(f)(::Missing, ::Missing) = missing
3✔
1580
    @eval $(f)(::Number, ::Missing) = missing
3✔
1581
    @eval $(f)(::Missing, ::Number) = missing
3✔
1582
end
1583

1584
exp2(x::AbstractFloat) = 2^x
1✔
1585
exp10(x::AbstractFloat) = 10^x
1✔
1586
clamp(::Missing, lo, hi) = missing
1✔
1587
fourthroot(::Missing) = missing
×
1588

1589
end # module
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc