Skip to content

Commit a61eca5

Browse files
committed
address review and align tests with C11 standard
1 parent f23a339 commit a61eca5

File tree

5 files changed

+30
-30
lines changed

5 files changed

+30
-30
lines changed

Doc/library/math.rst

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -253,8 +253,10 @@ Floating point arithmetic
253253

254254
Get the larger of two floating-point values, treating NaNs as missing data.
255255

256-
When both operands are NaNs, return ``nan`` (the sign of the result is
257-
implementation-defined).
256+
When both operands are (signed) NaNs or zeroes, return ``nan`` and ``0``
257+
respectively and the sign of the result is implementation-defined, that
258+
is, :func:`!fmax` is not required to be sensitive to the sign of such
259+
operands (see ISO C11, Annexes F.10.0.3 and F.10.9.2).
258260

259261
.. versionadded:: next
260262

@@ -263,8 +265,10 @@ Floating point arithmetic
263265

264266
Get the smaller of two floating-point values, treating NaNs as missing data.
265267

266-
When both operands are NaNs, return ``nan`` (the sign of the result is
267-
implementation-defined).
268+
When both operands are (signed) NaNs or zeroes, return ``nan`` and ``0``
269+
respectively and the sign of the result is implementation-defined, that
270+
is, :func:`!fmin` is not required to be sensitive to the sign of such
271+
operands (see ISO C11, Annexes F.10.0.3 and F.10.9.3).
268272

269273
.. versionadded:: next
270274

Lib/test/test_math.py

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -629,8 +629,9 @@ def test_fmax(self):
629629
self.assertRaises(TypeError, math.fmax, 'x', 'y')
630630

631631
self.assertEqual(math.fmax(0., 0.), 0.)
632-
self.assertEqual(math.fmax(0., -0.), 0.)
633-
self.assertEqual(math.fmax(-0., 0.), 0.)
632+
# fmax() does not need to be sensitive to the sign of 0 (F.10.9.2.3).
633+
self.assertIn(math.fmax(0., -0.), {-0., 0.})
634+
self.assertIn(math.fmax(-0., 0.), {-0., 0.})
634635

635636
self.assertEqual(math.fmax(1., 0.), 1.)
636637
self.assertEqual(math.fmax(0., 1.), 1.)
@@ -645,26 +646,23 @@ def test_fmax(self):
645646
for x in [NINF, -1., -0., 0., 1., INF]:
646647
self.assertFalse(math.isnan(x))
647648

648-
with self.subTest("math.fmax(INF, x)", x=x):
649+
with self.subTest(x=x, is_negative=math.copysign(1, x) < 0):
649650
self.assertEqual(math.fmax(INF, x), INF)
650-
with self.subTest("math.fmax(x, INF)", x=x):
651651
self.assertEqual(math.fmax(x, INF), INF)
652-
653-
with self.subTest("math.fmax(NINF, x)", x=x):
654652
self.assertEqual(math.fmax(NINF, x), x)
655-
with self.subTest("math.fmax(x, NINF)", x=x):
656653
self.assertEqual(math.fmax(x, NINF), x)
657654

658655
@requires_IEEE_754
659656
def test_fmax_nans(self):
660657
# When exactly one operand is NaN, the other is returned.
661658
for x in [NINF, -1., -0., 0., 1., INF]:
662-
with self.subTest(x=x):
659+
with self.subTest(x=x, is_negative=math.copysign(1, x) < 0):
663660
self.assertFalse(math.isnan(math.fmax(NAN, x)))
664661
self.assertFalse(math.isnan(math.fmax(x, NAN)))
665662
self.assertFalse(math.isnan(math.fmax(NNAN, x)))
666663
self.assertFalse(math.isnan(math.fmax(x, NNAN)))
667-
# When both operands are NaNs, fmax() returns NaN (see C11, F.10.9.2).
664+
# When both operands are NaNs, fmax() returns NaN (see C11, F.10.9.2)
665+
# whose sign is implementation-defined (see C11, F.10.0.3).
668666
self.assertTrue(math.isnan(math.fmax(NAN, NAN)))
669667
self.assertTrue(math.isnan(math.fmax(NNAN, NNAN)))
670668
self.assertTrue(math.isnan(math.fmax(NAN, NNAN)))
@@ -675,8 +673,9 @@ def test_fmin(self):
675673
self.assertRaises(TypeError, math.fmin, 'x', 'y')
676674

677675
self.assertEqual(math.fmin(0., 0.), 0.)
678-
self.assertEqual(math.fmin(0., -0.), -0.)
679-
self.assertEqual(math.fmin(-0., 0.), -0.)
676+
# fmin() does not need to be sensitive to the sign of 0 (F.10.9.3.1).
677+
self.assertIn(math.fmin(0., -0.), {-0., 0.})
678+
self.assertIn(math.fmin(-0., 0.), {-0., 0.})
680679

681680
self.assertEqual(math.fmin(1., 0.), 0.)
682681
self.assertEqual(math.fmin(0., 1.), 0.)
@@ -691,26 +690,23 @@ def test_fmin(self):
691690
for x in [NINF, -1., -0., 0., 1., INF]:
692691
self.assertFalse(math.isnan(x))
693692

694-
with self.subTest("math.fmin(INF, x)", x=x):
693+
with self.subTest(x=x, is_negative=math.copysign(1, x) < 0):
695694
self.assertEqual(math.fmin(INF, x), x)
696-
with self.subTest("math.fmin(x, INF)", x=x):
697695
self.assertEqual(math.fmin(x, INF), x)
698-
699-
with self.subTest("math.fmin(NINF, x)", x=x):
700696
self.assertEqual(math.fmin(NINF, x), NINF)
701-
with self.subTest("math.fmin(x, NINF)", x=x):
702697
self.assertEqual(math.fmin(x, NINF), NINF)
703698

704699
@requires_IEEE_754
705700
def test_fmin_nans(self):
706701
# When exactly one operand is NaN, the other is returned.
707702
for x in [NINF, -1., -0., 0., 1., INF]:
708-
with self.subTest(x=x):
703+
with self.subTest(x=x, is_negative=math.copysign(1, x) < 0):
709704
self.assertFalse(math.isnan(math.fmin(NAN, x)))
710705
self.assertFalse(math.isnan(math.fmin(x, NAN)))
711706
self.assertFalse(math.isnan(math.fmin(NNAN, x)))
712707
self.assertFalse(math.isnan(math.fmin(x, NNAN)))
713-
# When both operands are NaNs, fmin() returns NaN (see C11, F.10.9.3).
708+
# When both operands are NaNs, fmin() returns NaN (see C11, F.10.9.2)
709+
# whose sign is implementation-defined (see C11, F.10.0.3).
714710
self.assertTrue(math.isnan(math.fmin(NAN, NAN)))
715711
self.assertTrue(math.isnan(math.fmin(NNAN, NNAN)))
716712
self.assertTrue(math.isnan(math.fmin(NAN, NNAN)))
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
Add :func:`math.fmax` and :math:`math.fmin` to get the larger and smaller of
1+
Add :func:`math.fmax` and :func:`math.fmin` to get the larger and smaller of
22
two floating-point values. Patch by Bénédikt Tran.

Modules/clinic/mathmodule.c.h

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Modules/mathmodule.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1221,12 +1221,12 @@ math.fmax -> double
12211221
y: double
12221222
/
12231223
1224-
Returns the larger of two floating-point arguments.
1224+
Return the larger of two floating-point arguments.
12251225
[clinic start generated code]*/
12261226

12271227
static double
12281228
math_fmax_impl(PyObject *module, double x, double y)
1229-
/*[clinic end generated code: output=00692358d312fee2 input=e64ab9f40a60f4f1]*/
1229+
/*[clinic end generated code: output=00692358d312fee2 input=021596c027336ffe]*/
12301230
{
12311231
return fmax(x, y);
12321232
}
@@ -1238,12 +1238,12 @@ math.fmin -> double
12381238
y: double
12391239
/
12401240
1241-
Returns the smaller of two floating-point arguments.
1241+
Return the smaller of two floating-point arguments.
12421242
[clinic start generated code]*/
12431243

12441244
static double
12451245
math_fmin_impl(PyObject *module, double x, double y)
1246-
/*[clinic end generated code: output=3d5b7826bd292dd9 input=f7b5c91de01d766f]*/
1246+
/*[clinic end generated code: output=3d5b7826bd292dd9 input=d12e64ccc33f878a]*/
12471247
{
12481248
return fmin(x, y);
12491249
}

0 commit comments

Comments
 (0)