Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/hypothesis/internal/cathetus.py: 14%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

21 statements  

1# This file is part of Hypothesis, which may be found at 

2# https://github.com/HypothesisWorks/hypothesis/ 

3# 

4# Copyright the Hypothesis Authors. 

5# Individual contributors are listed in AUTHORS.rst and the git log. 

6# 

7# This Source Code Form is subject to the terms of the Mozilla Public License, 

8# v. 2.0. If a copy of the MPL was not distributed with this file, You can 

9# obtain one at https://mozilla.org/MPL/2.0/. 

10 

11from math import fabs, inf, isinf, isnan, nan, sqrt 

12from sys import float_info 

13 

14 

15def cathetus(h, a): 

16 """Given the lengths of the hypotenuse and a side of a right triangle, 

17 return the length of the other side. 

18 

19 A companion to the C99 hypot() function. Some care is needed to avoid 

20 underflow in the case of small arguments, and overflow in the case of 

21 large arguments as would occur for the naive implementation as 

22 sqrt(h*h - a*a). The behaviour with respect the non-finite arguments 

23 (NaNs and infinities) is designed to be as consistent as possible with 

24 the C99 hypot() specifications. 

25 

26 This function relies on the system ``sqrt`` function and so, like it, 

27 may be inaccurate up to a relative error of (around) floating-point 

28 epsilon. 

29 

30 Based on the C99 implementation https://github.com/jjgreen/cathetus 

31 """ 

32 if isnan(h): 

33 return nan 

34 

35 if isinf(h): 

36 if isinf(a): 

37 return nan 

38 else: 

39 # Deliberately includes the case when isnan(a), because the 

40 # C99 standard mandates that hypot(inf, nan) == inf 

41 return inf 

42 

43 h = fabs(h) 

44 a = fabs(a) 

45 

46 if h < a: 

47 return nan 

48 

49 # Thanks to floating-point precision issues when performing multiple 

50 # operations on extremely large or small values, we may rarely calculate 

51 # a side length that is longer than the hypotenuse. This is clearly an 

52 # error, so we clip to the hypotenuse as the best available estimate. 

53 if h > sqrt(float_info.max): 

54 if h > float_info.max / 2: 

55 b = sqrt(h - a) * sqrt(h / 2 + a / 2) * sqrt(2) 

56 else: 

57 b = sqrt(h - a) * sqrt(h + a) 

58 elif h < sqrt(float_info.min): 

59 b = sqrt(h - a) * sqrt(h + a) 

60 else: 

61 b = sqrt((h - a) * (h + a)) 

62 return min(b, h)