authorgravatar for kiyonnxperiaz@gmail.comTemariVirus <kiyonnxperiaz@gmail.com> 2025-12-13 05:34:12+08:00
committergravatar for kiyonnxperiaz@gmail.comTemariVirus <kiyonnxperiaz@gmail.com> 2026-03-16 15:42:35+08:00
loge4985509520445e3fb7c765149863b4ce6121738
treea1463d2fb655751289612e7f73e2cfb368d7fe89
parent06d9ab7121c30e4142e48908ed8ef79c3387ad30
signaturebadge-check Signed by SSH key SHA256:+zAK94uwewsXTNmaLt3PC6gO2ZcmUQey3+5ib4pNN3k

std.math.pow: organise and add special case tests

Added tests for special cases which were previously untested. Updated comments to use the same language as IEEE 754-2008.

1 files changed, 73 insertions(+), 32 deletions(-)

lib/std/math/pow.zig+73-32
...@@ -13,13 +13,13 @@ const expect = std.testing.expect;...@@ -13,13 +13,13 @@ const expect = std.testing.expect;
13/// - pow(x, +-0) = 1 for any x13/// - pow(x, +-0) = 1 for any x
14/// - pow(1, y) = 1 for any y14/// - pow(1, y) = 1 for any y
15/// - pow(x, 1) = x for any x15/// - pow(x, 1) = x for any x
16/// - pow(nan, y) = nan16/// - pow(nan, y) = nan for any y != 0
17/// - pow(x, nan) = nan17/// - pow(x, nan) = nan for any x != 1
18/// - pow(+-0, y) = +-inf for y an odd integer < 018/// - pow(+-0, y) = +-inf for y an odd integer < 0
19/// - pow(+-0, -inf) = +inf19/// - pow(+-0, -inf) = +inf
20/// - pow(+-0, +inf) = +020/// - pow(+-0, +inf) = +0
21/// - pow(+-0, y) = +inf for finite y < 0 and not an odd integer21/// - pow(+-0, y) = +inf for finite y < 0 and not an odd integer
22/// - pow(+-0, y) = +-0 for y an odd integer > 022/// - pow(+-0, y) = +-0 for finite y an odd integer > 0
23/// - pow(+-0, y) = +0 for finite y > 0 and not an odd integer23/// - pow(+-0, y) = +0 for finite y > 0 and not an odd integer
24/// - pow(-1, +-inf) = 124/// - pow(-1, +-inf) = 1
25/// - pow(x, +inf) = +inf for |x| > 125/// - pow(x, +inf) = +inf for |x| > 1
...@@ -39,20 +39,20 @@ pub fn pow(comptime T: type, x: T, y: T) T {...@@ -39,20 +39,20 @@ pub fn pow(comptime T: type, x: T, y: T) T {
39 @compileError("pow not implemented for " ++ @typeName(T));39 @compileError("pow not implemented for " ++ @typeName(T));
40 }40 }
4141
42 // pow(x, +-0) = 1 for all x42 // pow(x, +-0) = 1 for any x
43 // pow(1, y) = 1 for all y43 // pow(1, y) = 1 for any y
44 if (y == 0 or x == 1) {44 if (y == 0 or x == 1) {
45 return 1;45 return 1;
46 }46 }
4747
48 // pow(nan, y) = nan for all y48 // pow(nan, y) = nan for any y != 0
49 // pow(x, nan) = nan for all x49 // pow(x, nan) = nan for any x != 1
50 if (math.isNan(x) or math.isNan(y)) {50 if (math.isNan(x) or math.isNan(y)) {
51 @branchHint(.unlikely);51 @branchHint(.unlikely);
52 return math.nan(T);52 return math.nan(T);
53 }53 }
5454
55 // pow(x, 1) = x for all x55 // pow(x, 1) = x for any x
56 if (y == 1) {56 if (y == 1) {
57 return x;57 return x;
58 }58 }
...@@ -77,7 +77,7 @@ pub fn pow(comptime T: type, x: T, y: T) T {...@@ -77,7 +77,7 @@ pub fn pow(comptime T: type, x: T, y: T) T {
77 }77 }
7878
79 if (math.isInf(y)) {79 if (math.isInf(y)) {
80 // pow(-1, inf) = 1 for all x80 // pow(-1, inf) = 1
81 if (x == -1) {81 if (x == -1) {
82 return 1.0;82 return 1.0;
83 }83 }
...@@ -222,45 +222,86 @@ test pow {...@@ -222,45 +222,86 @@ test pow {
222}222}
223223
224test "special" {224test "special" {
225 const epsilon = 0.000001;225 // pow(x, +-0) = 1 for any x
226
227 try expect(pow(f32, 4, 0.0) == 1.0);226 try expect(pow(f32, 4, 0.0) == 1.0);
228 try expect(pow(f32, 7, -0.0) == 1.0);227 try expect(pow(f32, 7, -0.0) == 1.0);
228 try expect(pow(f32, math.nan(f32), -0.0) == 1.0);
229 // pow(1, y) = 1 for any y
230 try expect(pow(f32, 1.0, 4) == 1.0);
231 try expect(pow(f32, 1.0, 7) == 1.0);
232 try expect(pow(f32, 1.0, -math.inf(f32)) == 1.0);
233 try expect(pow(f32, 1.0, math.nan(f32)) == 1.0);
234 // pow(x, 1) = x for any x
229 try expect(pow(f32, 45, 1.0) == 45);235 try expect(pow(f32, 45, 1.0) == 45);
230 try expect(pow(f32, -45, 1.0) == -45);236 try expect(pow(f32, -45, 1.0) == -45);
237 try expect(math.isPositiveZero(pow(f32, 0.0, 1.0)));
238 try expect(math.isNegativeZero(pow(f32, -0.0, 1.0)));
239 try expect(math.isPositiveInf(pow(f32, math.inf(f32), 1.0)));
240 try expect(math.isNan(pow(f32, math.nan(f32), 1.0)));
241 // pow(nan, y) = nan for any y != 0
231 try expect(math.isNan(pow(f32, math.nan(f32), 5.0)));242 try expect(math.isNan(pow(f32, math.nan(f32), 5.0)));
232 try expect(math.isPositiveInf(pow(f32, -math.inf(f32), 0.5)));243 // pow(x, nan) = nan for any x != 1
233 try expect(math.isPositiveInf(pow(f32, -0.0, -0.5)));
234 try expect(pow(f32, -0.0, 0.5) == 0);
235 try expect(math.isNan(pow(f32, 5.0, math.nan(f32))));244 try expect(math.isNan(pow(f32, 5.0, math.nan(f32))));
245 // pow(+-0, y) = +-inf for y an odd integer < 0
236 try expect(math.isPositiveInf(pow(f32, 0.0, -1.0)));246 try expect(math.isPositiveInf(pow(f32, 0.0, -1.0)));
237 //expect(math.isNegativeInf(pow(f32, -0.0, -3.0))); TODO is this required?247 try expect(math.isNegativeInf(pow(f32, -0.0, -5.0)));
248 // pow(+-0, -inf) = +inf
238 try expect(math.isPositiveInf(pow(f32, 0.0, -math.inf(f32))));249 try expect(math.isPositiveInf(pow(f32, 0.0, -math.inf(f32))));
239 try expect(math.isPositiveInf(pow(f32, -0.0, -math.inf(f32))));250 try expect(math.isPositiveInf(pow(f32, -0.0, -math.inf(f32))));
240 try expect(pow(f32, 0.0, math.inf(f32)) == 0.0);251 // pow(+-0, +inf) = +0
241 try expect(pow(f32, -0.0, math.inf(f32)) == 0.0);252 try expect(math.isPositiveZero(pow(f32, 0.0, math.inf(f32))));
253 try expect(math.isPositiveZero(pow(f32, -0.0, math.inf(f32))));
254 // pow(+-0, y) = +inf for finite y < 0 and not an odd integer
242 try expect(math.isPositiveInf(pow(f32, 0.0, -2.0)));255 try expect(math.isPositiveInf(pow(f32, 0.0, -2.0)));
243 try expect(math.isPositiveInf(pow(f32, -0.0, -2.0)));256 try expect(math.isPositiveInf(pow(f32, -0.0, -2.0)));
244 try expect(pow(f32, 0.0, 1.0) == 0.0);257 try expect(math.isPositiveInf(pow(f32, 0.0, -5.2)));
245 try expect(pow(f32, -0.0, 1.0) == -0.0);258 try expect(math.isPositiveInf(pow(f32, -0.0, -0.5)));
246 try expect(pow(f32, 0.0, 2.0) == 0.0);259 // pow(+-0, y) = +-0 for finite y an odd integer > 0
247 try expect(pow(f32, -0.0, 2.0) == 0.0);260 try expect(math.isPositiveZero(pow(f32, 0.0, 3.0)));
248 try expect(math.approxEqAbs(f32, pow(f32, -1.0, math.inf(f32)), 1.0, epsilon));261 try expect(math.isNegativeZero(pow(f32, -0.0, 5.0)));
249 try expect(math.approxEqAbs(f32, pow(f32, -1.0, -math.inf(f32)), 1.0, epsilon));262 // pow(+-0, y) = +0 for finite y > 0 and not an odd integer
263 try expect(math.isPositiveZero(pow(f32, 0.0, 2.0)));
264 try expect(math.isPositiveZero(pow(f32, -0.0, 2.0)));
265 try expect(math.isPositiveZero(pow(f32, 0.0, 5.2)));
266 try expect(math.isPositiveZero(pow(f32, -0.0, 0.5)));
267 // pow(-1, +-inf) = 1
268 try expect(pow(f32, -1.0, math.inf(f32)) == 1.0);
269 try expect(pow(f32, -1.0, -math.inf(f32)) == 1.0);
270 // pow(x, +inf) = +inf for |x| > 1
250 try expect(math.isPositiveInf(pow(f32, 1.2, math.inf(f32))));271 try expect(math.isPositiveInf(pow(f32, 1.2, math.inf(f32))));
251 try expect(math.isPositiveInf(pow(f32, -1.2, math.inf(f32))));272 try expect(math.isPositiveInf(pow(f32, -1.2, math.inf(f32))));
252 try expect(pow(f32, 1.2, -math.inf(f32)) == 0.0);273 // pow(x, -inf) = +0 for |x| > 1
253 try expect(pow(f32, -1.2, -math.inf(f32)) == 0.0);274 try expect(math.isPositiveZero(pow(f32, 1.2, -math.inf(f32))));
254 try expect(pow(f32, 0.2, math.inf(f32)) == 0.0);275 try expect(math.isPositiveZero(pow(f32, -1.2, -math.inf(f32))));
255 try expect(pow(f32, -0.2, math.inf(f32)) == 0.0);276 // pow(x, +inf) = +0 for |x| < 1
277 try expect(math.isPositiveZero(pow(f32, 0.2, math.inf(f32))));
278 try expect(math.isPositiveZero(pow(f32, -0.2, math.inf(f32))));
279 // pow(x, -inf) = +inf for |x| < 1
256 try expect(math.isPositiveInf(pow(f32, 0.2, -math.inf(f32))));280 try expect(math.isPositiveInf(pow(f32, 0.2, -math.inf(f32))));
257 try expect(math.isPositiveInf(pow(f32, -0.2, -math.inf(f32))));281 try expect(math.isPositiveInf(pow(f32, -0.2, -math.inf(f32))));
258 try expect(math.isPositiveInf(pow(f32, math.inf(f32), 1.0)));282 // pow(+inf, y) = +inf for y > 0
259 try expect(pow(f32, math.inf(f32), -1.0) == 0.0);283 try expect(math.isPositiveInf(pow(f32, math.inf(f32), 2.0)));
260 //expect(pow(f32, -math.inf(f32), 5.0) == pow(f32, -0.0, -5.0)); TODO support negative 0?284 try expect(math.isPositiveInf(pow(f32, math.inf(f32), 0.2)));
261 try expect(pow(f32, -math.inf(f32), -5.2) == pow(f32, -0.0, 5.2));285 // pow(+inf, y) = +0 for y < 0
286 try expect(math.isPositiveZero(pow(f32, math.inf(f32), -2.0)));
287 try expect(math.isPositiveZero(pow(f32, math.inf(f32), -0.2)));
288 // pow(-inf, y) = -inf for y an odd integer > 0
289 try expect(math.isNegativeInf(pow(f32, -math.inf(f32), 5.0)));
290 // pow(-inf, +inf) = +inf
291 try expect(math.isPositiveInf(pow(f32, -math.inf(f32), math.inf(f32))));
292 // pow(-inf, -inf) = +0
293 try expect(math.isPositiveZero(pow(f32, -math.inf(f32), -math.inf(f32))));
294 // pow(-inf, y) = +inf for finite y > 0 and not an odd integer
295 try expect(math.isPositiveInf(pow(f32, -math.inf(f32), 4.0)));
296 try expect(math.isPositiveInf(pow(f32, -math.inf(f32), 0.5)));
297 // pow(-inf, y) = -0 for finite y an odd integer < 0
298 try expect(math.isNegativeZero(pow(f32, -math.inf(f32), -3.0)));
299 // pow(-inf, y) = +0 for finite y < 0 and not an odd integer
300 try expect(math.isPositiveZero(pow(f32, -math.inf(f32), -2.0)));
301 try expect(math.isPositiveZero(pow(f32, -math.inf(f32), -5.2)));
302 // pow(x, y) = nan for finite x < 0 and finite non-integer y
262 try expect(math.isNan(pow(f32, -1.0, 1.2)));303 try expect(math.isNan(pow(f32, -1.0, 1.2)));
263 try expect(math.isNan(pow(f32, -12.4, 78.5)));304 try expect(math.isNan(pow(f32, -12.4, -78.5)));
264}305}
265306
266test "overflow" {307test "overflow" {