# -*- coding: utf-8 -*-
"""
Функции для работы с мантиссой и порядком.
"""
from .epsilon import epsilon
from math import modf, fabs, log10, floor

__author__ = "Zasimov Alexey"
__email__ = "zasimov-a@yandex-team.ru"


def mc(x, func=float):
    """
    Определяет мантиссу и порядок числа.
    Возвращает: 1 <= |x| < 10 (float) - нормализованная научная запись, 
                c - целое.

    >>> mc(0)
    (0.0, 0)
    >>> mc(1)
    (1.0, 0)
    >>> mc(2.345)
    (2.345, 0)
    >>> mc(10.0)
    (1.0, 1)
    >>> mc(0.2)
    (2.0, -1)
    >>> mc(0.00345)
    (3.45, -3)
    """
    x = func(x)
    if x == 0:
        return 0.0, 0
    c = 0
    while x < 1:
        x = x * 10
        c -= 1
    while x >= 10:
        x = x / 10
        c += 1
    return x, c


def mc10(x, func=float):
    """
    Аналог функции mc, только более быстрый.

    >>> mc10(0)
    (0.0, 0)
    >>> mc10(1)
    (1.0, 0)
    >>> mc10(2.345)
    (2.345, 0)
    >>> mc10(10.0)
    (1.0, 1)
    >>> mc10(0.2)
    (2.0, -1)
    >>> mc10(0.00345)
    (3.4499999999999997, -3)
    """
    x = func(x)
    if fabs(x) <= epsilon:
        return x, 0
    c = int(floor(log10(x)))
    return x * (10 ** (-c)), c


def mantissa(x, max_precision=None, func=float):
    """
    Возвращает целое число и порядок.
    """
    x = func(x)
    c = 0
    while True:
        f, _ = modf(x)
        if fabs(f) <= epsilon:
            return int(x), c
        if -c == max_precision:
            return int(x), c
        x = x * 10
        c -= 1
