Skip to content
This repository has been archived by the owner on Apr 26, 2020. It is now read-only.

Implementing Float.as_integer_ratio() #1

Closed
AnimeshSinha1309 opened this issue Dec 28, 2018 · 2 comments
Closed

Implementing Float.as_integer_ratio() #1

AnimeshSinha1309 opened this issue Dec 28, 2018 · 2 comments
Assignees
Labels
function Implementing a single function in the Library

Comments

@AnimeshSinha1309
Copy link
Owner

The implement the conversion of a Float to a rational number represented as a Tuple.

@AnimeshSinha1309 AnimeshSinha1309 added the function Implementing a single function in the Library label Dec 28, 2018
@AnimeshSinha1309 AnimeshSinha1309 self-assigned this Dec 28, 2018
@AnimeshSinha1309
Copy link
Owner Author

This is the implementation of the as_integer_ratio() function in CPython.

    def as_integer_ratio(self):
        """Express a finite Decimal instance in the form n / d.
        Returns a pair (n, d) of integers.  When called on an infinity
        or NaN, raises OverflowError or ValueError respectively.
        >>> Decimal('3.14').as_integer_ratio()
        (157, 50)
        >>> Decimal('-123e5').as_integer_ratio()
        (-12300000, 1)
        >>> Decimal('0.00').as_integer_ratio()
        (0, 1)
        """
        if self._is_special:
            if self.is_nan():
                raise ValueError("cannot convert NaN to integer ratio")
            else:
                raise OverflowError("cannot convert Infinity to integer ratio")
        if not self:
            return 0, 1
        # Find n, d in lowest terms such that abs(self) == n / d;
        # we'll deal with the sign later.
        n = int(self._int)
        if self._exp >= 0:
            # self is an integer.
            n, d = n * 10**self._exp, 1
        else:
            # Find d2, d5 such that abs(self) = n / (2**d2 * 5**d5).
            d5 = -self._exp
            while d5 > 0 and n % 5 == 0:
                n //= 5
                d5 -= 1
            # (n & -n).bit_length() - 1 counts trailing zeros in binary
            # representation of n (provided n is nonzero).
            d2 = -self._exp
            shift2 = min((n & -n).bit_length() - 1, d2)
            if shift2:
                n >>= shift2
                d2 -= shift2
            d = 5**d5 << d2
        if self._sign:
            n = -n
        return n, d

@AnimeshSinha1309
Copy link
Owner Author

AnimeshSinha1309 commented Dec 28, 2018

Things to note about porting the code to Java:

  • The numbers are represented as (-1)**_sign * _int * 10**_exp. Converting x._exp to Math.log10(x). And x._int will convert to (double) x / (Math.pow(10, Math.log10(x))).
  • Python's x // y is integer division (getting the quotient). (int) x / y and The Shift operators x << y and x >> y have the typical behavior as in C++. The python Power operator (x ** y) will be converted to Math.pow(x, y).
  • int.bit_length(x) tells the length of binary representation of the number. It converts to Math.ceil(Math.log(x)/Math.log(2))
  • The raise error syntax in Java is throw new org.python.exceptions.ErrorName("Error Message String")
  • is_special keeps track of all special cases like is_nan, is_inf, etc. The direct conversion has not been implemented in the class yet.

Returning Tuples is the only remaining issue. Will instantiate, add a couple of objects, and return the Tuple.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
function Implementing a single function in the Library
Projects
None yet
Development

No branches or pull requests

1 participant