test_scalar_methods.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. """
  2. Test the scalar constructors, which also do type-coercion
  3. """
  4. import fractions
  5. import platform
  6. import pytest
  7. import numpy as np
  8. from numpy.testing import assert_equal, assert_raises
  9. class TestAsIntegerRatio:
  10. # derived in part from the cpython test "test_floatasratio"
  11. @pytest.mark.parametrize("ftype", [
  12. np.half, np.single, np.double, np.longdouble])
  13. @pytest.mark.parametrize("f, ratio", [
  14. (0.875, (7, 8)),
  15. (-0.875, (-7, 8)),
  16. (0.0, (0, 1)),
  17. (11.5, (23, 2)),
  18. ])
  19. def test_small(self, ftype, f, ratio):
  20. assert_equal(ftype(f).as_integer_ratio(), ratio)
  21. @pytest.mark.parametrize("ftype", [
  22. np.half, np.single, np.double, np.longdouble])
  23. def test_simple_fractions(self, ftype):
  24. R = fractions.Fraction
  25. assert_equal(R(0, 1),
  26. R(*ftype(0.0).as_integer_ratio()))
  27. assert_equal(R(5, 2),
  28. R(*ftype(2.5).as_integer_ratio()))
  29. assert_equal(R(1, 2),
  30. R(*ftype(0.5).as_integer_ratio()))
  31. assert_equal(R(-2100, 1),
  32. R(*ftype(-2100.0).as_integer_ratio()))
  33. @pytest.mark.parametrize("ftype", [
  34. np.half, np.single, np.double, np.longdouble])
  35. def test_errors(self, ftype):
  36. assert_raises(OverflowError, ftype('inf').as_integer_ratio)
  37. assert_raises(OverflowError, ftype('-inf').as_integer_ratio)
  38. assert_raises(ValueError, ftype('nan').as_integer_ratio)
  39. def test_against_known_values(self):
  40. R = fractions.Fraction
  41. assert_equal(R(1075, 512),
  42. R(*np.half(2.1).as_integer_ratio()))
  43. assert_equal(R(-1075, 512),
  44. R(*np.half(-2.1).as_integer_ratio()))
  45. assert_equal(R(4404019, 2097152),
  46. R(*np.single(2.1).as_integer_ratio()))
  47. assert_equal(R(-4404019, 2097152),
  48. R(*np.single(-2.1).as_integer_ratio()))
  49. assert_equal(R(4728779608739021, 2251799813685248),
  50. R(*np.double(2.1).as_integer_ratio()))
  51. assert_equal(R(-4728779608739021, 2251799813685248),
  52. R(*np.double(-2.1).as_integer_ratio()))
  53. # longdouble is platform dependent
  54. @pytest.mark.parametrize("ftype, frac_vals, exp_vals", [
  55. # dtype test cases generated using hypothesis
  56. # first five generated cases per dtype
  57. (np.half, [0.0, 0.01154830649280303, 0.31082276347447274,
  58. 0.527350517124794, 0.8308562335072596],
  59. [0, 1, 0, -8, 12]),
  60. (np.single, [0.0, 0.09248576989263226, 0.8160498218131407,
  61. 0.17389442853722373, 0.7956044195067877],
  62. [0, 12, 10, 17, -26]),
  63. (np.double, [0.0, 0.031066908499895136, 0.5214135908877832,
  64. 0.45780736035689296, 0.5906586745934036],
  65. [0, -801, 51, 194, -653]),
  66. pytest.param(
  67. np.longdouble,
  68. [0.0, 0.20492557202724854, 0.4277180662199366, 0.9888085019891495,
  69. 0.9620175814461964],
  70. [0, -7400, 14266, -7822, -8721],
  71. marks=[
  72. pytest.mark.skipif(
  73. np.finfo(np.double) == np.finfo(np.longdouble),
  74. reason="long double is same as double"),
  75. pytest.mark.skipif(
  76. platform.machine().startswith("ppc"),
  77. reason="IBM double double"),
  78. ]
  79. )
  80. ])
  81. def test_roundtrip(self, ftype, frac_vals, exp_vals):
  82. for frac, exp in zip(frac_vals, exp_vals):
  83. f = np.ldexp(frac, exp, dtype=ftype)
  84. n, d = f.as_integer_ratio()
  85. try:
  86. # workaround for gh-9968
  87. nf = np.longdouble(str(n))
  88. df = np.longdouble(str(d))
  89. except (OverflowError, RuntimeWarning):
  90. # the values may not fit in any float type
  91. pytest.skip("longdouble too small on this platform")
  92. assert_equal(nf / df, f, "{}/{}".format(n, d))