|
1 | | -using Base: BitInteger, promote, afoldl, @_inline_meta |
2 | | -import Base.Checked: checked_neg, checked_add, checked_sub, checked_mul, checked_abs, |
3 | | - checked_div, checked_fld, checked_cld, checked_mod, checked_rem |
4 | | -using Base.Checked: mul_with_overflow |
5 | | - |
6 | | -if VERSION ≥ v"1.11-alpha" |
7 | | - import Base: power_by_squaring |
8 | | - import Base.Checked: checked_pow |
9 | | -else |
10 | | - using Base: throw_domerr_powbysq, to_power_type |
11 | | - using Base.Checked: throw_overflowerr_binaryop |
12 | | -end |
13 | | - |
14 | 1 | # resolve ambiguity when `-` used as symbol |
15 | 2 | checked_negsub(x) = checked_neg(x) |
16 | 3 | checked_negsub(x, y) = checked_sub(x, y) |
@@ -87,3 +74,19 @@ if VERSION < v"1.11" |
87 | 74 | return y |
88 | 75 | end |
89 | 76 | end |
| 77 | + |
| 78 | +# adapted from Base intfuncs.jl; negative literal powers promote to floating point |
| 79 | +@inline literal_pow(::typeof(checked_pow), x::BitInteger, ::Val{0}) = one(x) |
| 80 | +@inline literal_pow(::typeof(checked_pow), x::BitInteger, ::Val{1}) = x |
| 81 | +@inline literal_pow(::typeof(checked_pow), x::BitInteger, ::Val{2}) = @checked x * x |
| 82 | +@inline literal_pow(::typeof(checked_pow), x::BitInteger, ::Val{3}) = @checked x * x * x |
| 83 | +@inline literal_pow(::typeof(checked_pow), x::BitInteger, ::Val{-1}) = literal_pow(^, x, Val(-1)) |
| 84 | +@inline literal_pow(::typeof(checked_pow), x::BitInteger, ::Val{-2}) = literal_pow(^, x, Val(-2)) |
| 85 | + |
| 86 | +@inline function literal_pow(f::typeof(checked_pow), x, ::Val{p}) where {p} |
| 87 | + if p < 0 |
| 88 | + literal_pow(^, x, Val(p)) |
| 89 | + else |
| 90 | + f(x, p) |
| 91 | + end |
| 92 | +end |
0 commit comments