@@ -599,102 +599,101 @@ def testfrexp(name, result, expected):
599
599
self .assertTrue (math .isnan (math .frexp (NAN )[0 ]))
600
600
601
601
602
- # TODO: RUSTPYTHON
603
- # @requires_IEEE_754
604
- # @unittest.skipIf(HAVE_DOUBLE_ROUNDING,
605
- # "fsum is not exact on machines with double rounding")
606
- # def testFsum(self):
607
- # # math.fsum relies on exact rounding for correct operation.
608
- # # There's a known problem with IA32 floating-point that causes
609
- # # inexact rounding in some situations, and will cause the
610
- # # math.fsum tests below to fail; see issue #2937. On non IEEE
611
- # # 754 platforms, and on IEEE 754 platforms that exhibit the
612
- # # problem described in issue #2937, we simply skip the whole
613
- # # test.
614
-
615
- # # Python version of math.fsum, for comparison. Uses a
616
- # # different algorithm based on frexp, ldexp and integer
617
- # # arithmetic.
618
- # from sys import float_info
619
- # mant_dig = float_info.mant_dig
620
- # etiny = float_info.min_exp - mant_dig
621
-
622
- # def msum(iterable):
623
- # """Full precision summation. Compute sum(iterable) without any
624
- # intermediate accumulation of error. Based on the 'lsum' function
625
- # at http://code.activestate.com/recipes/393090/
626
- # """
627
- # tmant, texp = 0, 0
628
- # for x in iterable:
629
- # mant, exp = math.frexp(x)
630
- # mant, exp = int(math.ldexp(mant, mant_dig)), exp - mant_dig
631
- # if texp > exp:
632
- # tmant <<= texp-exp
633
- # texp = exp
634
- # else:
635
- # mant <<= exp-texp
636
- # tmant += mant
637
- # # Round tmant * 2**texp to a float. The original recipe
638
- # # used float(str(tmant)) * 2.0**texp for this, but that's
639
- # # a little unsafe because str -> float conversion can't be
640
- # # relied upon to do correct rounding on all platforms.
641
- # tail = max(len(bin(abs(tmant)))-2 - mant_dig, etiny - texp)
642
- # if tail > 0:
643
- # h = 1 << (tail-1)
644
- # tmant = tmant // (2*h) + bool(tmant & h and tmant & 3*h-1)
645
- # texp += tail
646
- # return math.ldexp(tmant, texp)
647
-
648
- # test_values = [
649
- # ([], 0.0),
650
- # ([0.0], 0.0),
651
- # ([1e100, 1.0, -1e100, 1e-100, 1e50, -1.0, -1e50], 1e-100),
652
- # ([2.0**53, -0.5, -2.0**-54], 2.0**53-1.0),
653
- # ([2.0**53, 1.0, 2.0**-100], 2.0**53+2.0),
654
- # ([2.0**53+10.0, 1.0, 2.0**-100], 2.0**53+12.0),
655
- # ([2.0**53-4.0, 0.5, 2.0**-54], 2.0**53-3.0),
656
- # ([1./n for n in range(1, 1001)],
657
- # float.fromhex('0x1.df11f45f4e61ap+2')),
658
- # ([(-1.)**n/n for n in range(1, 1001)],
659
- # float.fromhex('-0x1.62a2af1bd3624p-1')),
660
- # ([1e16, 1., 1e-16], 10000000000000002.0),
661
- # ([1e16-2., 1.-2.**-53, -(1e16-2.), -(1.-2.**-53)], 0.0),
662
- # # exercise code for resizing partials array
663
- # ([2.**n - 2.**(n+50) + 2.**(n+52) for n in range(-1074, 972, 2)] +
664
- # [-2.**1022],
665
- # float.fromhex('0x1.5555555555555p+970')),
666
- # ]
667
-
668
- # # Telescoping sum, with exact differences (due to Sterbenz)
669
- # terms = [1.7**i for i in range(1001)]
670
- # test_values.append((
671
- # [terms[i+1] - terms[i] for i in range(1000)] + [-terms[1000]],
672
- # -terms[0]
673
- # ))
674
-
675
- # for i, (vals, expected) in enumerate(test_values):
676
- # try:
677
- # actual = math.fsum(vals)
678
- # except OverflowError:
679
- # self.fail("test %d failed: got OverflowError, expected %r "
680
- # "for math.fsum(%.100r)" % (i, expected, vals))
681
- # except ValueError:
682
- # self.fail("test %d failed: got ValueError, expected %r "
683
- # "for math.fsum(%.100r)" % (i, expected, vals))
684
- # self.assertEqual(actual, expected)
685
-
686
- # from random import random, gauss, shuffle
687
- # for j in range(1000):
688
- # vals = [7, 1e100, -7, -1e100, -9e-20, 8e-20] * 10
689
- # s = 0
690
- # for i in range(200):
691
- # v = gauss(0, random()) ** 7 - s
692
- # s += v
693
- # vals.append(v)
694
- # shuffle(vals)
695
-
696
- # s = msum(vals)
697
- # self.assertEqual(msum(vals), math.fsum(vals))
602
+ @requires_IEEE_754
603
+ @unittest .skipIf (HAVE_DOUBLE_ROUNDING ,
604
+ "fsum is not exact on machines with double rounding" )
605
+ def testFsum (self ):
606
+ # math.fsum relies on exact rounding for correct operation.
607
+ # There's a known problem with IA32 floating-point that causes
608
+ # inexact rounding in some situations, and will cause the
609
+ # math.fsum tests below to fail; see issue #2937. On non IEEE
610
+ # 754 platforms, and on IEEE 754 platforms that exhibit the
611
+ # problem described in issue #2937, we simply skip the whole
612
+ # test.
613
+
614
+ # Python version of math.fsum, for comparison. Uses a
615
+ # different algorithm based on frexp, ldexp and integer
616
+ # arithmetic.
617
+ from sys import float_info
618
+ mant_dig = float_info .mant_dig
619
+ etiny = float_info .min_exp - mant_dig
620
+
621
+ def msum (iterable ):
622
+ """Full precision summation. Compute sum(iterable) without any
623
+ intermediate accumulation of error. Based on the 'lsum' function
624
+ at http://code.activestate.com/recipes/393090/
625
+ """
626
+ tmant , texp = 0 , 0
627
+ for x in iterable :
628
+ mant , exp = math .frexp (x )
629
+ mant , exp = int (math .ldexp (mant , mant_dig )), exp - mant_dig
630
+ if texp > exp :
631
+ tmant <<= texp - exp
632
+ texp = exp
633
+ else :
634
+ mant <<= exp - texp
635
+ tmant += mant
636
+ # Round tmant * 2**texp to a float. The original recipe
637
+ # used float(str(tmant)) * 2.0**texp for this, but that's
638
+ # a little unsafe because str -> float conversion can't be
639
+ # relied upon to do correct rounding on all platforms.
640
+ tail = max (len (bin (abs (tmant )))- 2 - mant_dig , etiny - texp )
641
+ if tail > 0 :
642
+ h = 1 << (tail - 1 )
643
+ tmant = tmant // (2 * h ) + bool (tmant & h and tmant & 3 * h - 1 )
644
+ texp += tail
645
+ return math .ldexp (tmant , texp )
646
+
647
+ test_values = [
648
+ ([], 0.0 ),
649
+ ([0.0 ], 0.0 ),
650
+ ([1e100 , 1.0 , - 1e100 , 1e-100 , 1e50 , - 1.0 , - 1e50 ], 1e-100 ),
651
+ ([2.0 ** 53 , - 0.5 , - 2.0 ** - 54 ], 2.0 ** 53 - 1.0 ),
652
+ ([2.0 ** 53 , 1.0 , 2.0 ** - 100 ], 2.0 ** 53 + 2.0 ),
653
+ ([2.0 ** 53 + 10.0 , 1.0 , 2.0 ** - 100 ], 2.0 ** 53 + 12.0 ),
654
+ ([2.0 ** 53 - 4.0 , 0.5 , 2.0 ** - 54 ], 2.0 ** 53 - 3.0 ),
655
+ ([1. / n for n in range (1 , 1001 )],
656
+ float .fromhex ('0x1.df11f45f4e61ap+2' )),
657
+ ([(- 1. )** n / n for n in range (1 , 1001 )],
658
+ float .fromhex ('-0x1.62a2af1bd3624p-1' )),
659
+ ([1e16 , 1. , 1e-16 ], 10000000000000002.0 ),
660
+ ([1e16 - 2. , 1. - 2. ** - 53 , - (1e16 - 2. ), - (1. - 2. ** - 53 )], 0.0 ),
661
+ # exercise code for resizing partials array
662
+ ([2. ** n - 2. ** (n + 50 ) + 2. ** (n + 52 ) for n in range (- 1074 , 972 , 2 )] +
663
+ [- 2. ** 1022 ],
664
+ float .fromhex ('0x1.5555555555555p+970' )),
665
+ ]
666
+
667
+ # Telescoping sum, with exact differences (due to Sterbenz)
668
+ terms = [1.7 ** i for i in range (1001 )]
669
+ test_values .append ((
670
+ [terms [i + 1 ] - terms [i ] for i in range (1000 )] + [- terms [1000 ]],
671
+ - terms [0 ]
672
+ ))
673
+
674
+ for i , (vals , expected ) in enumerate (test_values ):
675
+ try :
676
+ actual = math .fsum (vals )
677
+ except OverflowError :
678
+ self .fail ("test %d failed: got OverflowError, expected %r "
679
+ "for math.fsum(%.100r)" % (i , expected , vals ))
680
+ except ValueError :
681
+ self .fail ("test %d failed: got ValueError, expected %r "
682
+ "for math.fsum(%.100r)" % (i , expected , vals ))
683
+ self .assertEqual (actual , expected )
684
+
685
+ from random import random , gauss , shuffle
686
+ for j in range (1000 ):
687
+ vals = [7 , 1e100 , - 7 , - 1e100 , - 9e-20 , 8e-20 ] * 10
688
+ s = 0
689
+ for i in range (200 ):
690
+ v = gauss (0 , random ()) ** 7 - s
691
+ s += v
692
+ vals .append (v )
693
+ shuffle (vals )
694
+
695
+ s = msum (vals )
696
+ self .assertEqual (msum (vals ), math .fsum (vals ))
698
697
699
698
700
699
# Python 3.9
@@ -1559,12 +1558,12 @@ def testIsinf(self):
1559
1558
# self.assertTrue(math.isnan(math.nan))
1560
1559
1561
1560
# TODO: RUSTPYTHON
1562
- # @requires_IEEE_754
1563
- # def test_inf_constant(self):
1564
- # self.assertTrue(math.isinf(math.inf))
1565
- # self.assertGreater(math.inf, 0.0)
1566
- # self.assertEqual(math.inf, float("inf"))
1567
- # self.assertEqual(-math.inf, float("-inf"))
1561
+ @requires_IEEE_754
1562
+ def test_inf_constant (self ):
1563
+ self .assertTrue (math .isinf (math .inf ))
1564
+ self .assertGreater (math .inf , 0.0 )
1565
+ self .assertEqual (math .inf , float ("inf" ))
1566
+ self .assertEqual (- math .inf , float ("-inf" ))
1568
1567
1569
1568
# RED_FLAG 16-Oct-2000 Tim
1570
1569
# While 2.0 is more consistent about exceptions than previous releases, it
0 commit comments