@@ -1140,10 +1140,6 @@ function modf(x::T) where T<:IEEEFloat
1140
1140
return (rx, ix)
1141
1141
end
1142
1142
1143
- @inline function use_power_by_squaring (n:: Integer )
1144
- - 2 ^ 12 <= n <= 3 * 2 ^ 13
1145
- end
1146
-
1147
1143
# @constprop aggressive to help the compiler see the switch between the integer and float
1148
1144
# variants for callers with constant `y`
1149
1145
@constprop :aggressive function ^ (x:: Float64 , y:: Float64 )
@@ -1156,33 +1152,24 @@ end
1156
1152
y = sign (y)* 0x1 .8 p62
1157
1153
end
1158
1154
yint = unsafe_trunc (Int64, y) # This is actually safe since julia freezes the result
1159
- yisint = y == yint
1160
- if yisint
1161
- yint == 0 && return 1.0
1162
- use_power_by_squaring (yint) && return @noinline pow_body (x, yint)
1163
- end
1164
- 2 * xu== 0 && return abs (y)* Inf * (! (y> 0 )) # if x === +0.0 or -0.0 (Inf * false === 0.0)
1165
- s = 1
1166
- if x < 0
1167
- ! yisint && throw_exp_domainerror (x) # y isn't an integer
1168
- s = ifelse (isodd (yint), - 1 , 1 )
1169
- end
1170
- ! isfinite (x) && return copysign (x,s)* (y> 0 || isnan (x)) # x is inf or NaN
1171
- return copysign (pow_body (abs (x), y), s)
1172
- end
1173
-
1174
- @assume_effects :foldable @noinline function pow_body (x:: Float64 , y:: Float64 )
1175
- xu = reinterpret (UInt64, x)
1155
+ y == yint && return @noinline x^ yint
1156
+ 2 * xu== 0 && return abs (y)* Inf * (! (y> 0 )) # if x==0
1157
+ x< 0 && throw_exp_domainerror (x) # |y| is small enough that y isn't an integer
1158
+ ! isfinite (x) && return x* (y> 0 || isnan (x)) # x is inf or NaN
1176
1159
if xu < (UInt64 (1 )<< 52 ) # x is subnormal
1177
1160
xu = reinterpret (UInt64, x * 0x1 p52) # normalize x
1178
1161
xu &= ~ sign_mask (Float64)
1179
1162
xu -= UInt64 (52 ) << 52 # mess with the exponent
1180
1163
end
1164
+ return pow_body (xu, y)
1165
+ end
1166
+
1167
+ @inline function pow_body (xu:: UInt64 , y:: Float64 )
1181
1168
logxhi,logxlo = _log_ext (xu)
1182
1169
xyhi, xylo = two_mul (logxhi,y)
1183
1170
xylo = muladd (logxlo, y, xylo)
1184
1171
hi = xyhi+ xylo
1185
- return @inline Base. Math. exp_impl (hi, xylo- (hi- xyhi), Val (:ℯ ))
1172
+ return Base. Math. exp_impl (hi, xylo- (hi- xyhi), Val (:ℯ ))
1186
1173
end
1187
1174
1188
1175
@constprop :aggressive function ^ (x:: T , y:: T ) where T <: Union{Float16, Float32}
@@ -1206,29 +1193,12 @@ end
1206
1193
return T (exp2 (log2 (abs (widen (x))) * y))
1207
1194
end
1208
1195
1196
+ # compensated power by squaring
1209
1197
@constprop :aggressive @inline function ^ (x:: Float64 , n:: Integer )
1210
- x^ clamp (n, Int64)
1211
- end
1212
- @constprop :aggressive @inline function ^ (x:: Float64 , n:: Int64 )
1213
1198
n == 0 && return one (x)
1214
- if use_power_by_squaring (n)
1215
- return pow_body (x, n)
1216
- else
1217
- s = ifelse (x < 0 && isodd (n), - 1.0 , 1.0 )
1218
- x = abs (x)
1219
- y = float (n)
1220
- if y == n
1221
- return copysign (pow_body (x, y), s)
1222
- else
1223
- n2 = n % 1024
1224
- y = float (n - n2)
1225
- return pow_body (x, y) * copysign (pow_body (x, n2), s)
1226
- end
1227
- end
1199
+ return pow_body (x, n)
1228
1200
end
1229
1201
1230
- # compensated power by squaring
1231
- # this method is only reliable for -2^20 < n < 2^20 (cf. #53881 #53886)
1232
1202
@assume_effects :terminates_locally @noinline function pow_body (x:: Float64 , n:: Integer )
1233
1203
y = 1.0
1234
1204
xnlo = ynlo = 0.0
0 commit comments