from ...forall import *
def perepolnenie():
    """
    Демонстрация поведения типов данных при переполнении в Python и NumPy.

    Parameters
    ----------
    Нет входных параметров

    Returns
    ----------
    None
        Функция только выводит информацию в консоль.

    Examples
    --------
    >>> perepolnenie()
    2147483647
    -2147483648
    1.7976931348623157e+308
    0.0
    inf

    Notes
    -----
    1. Для int32 (32-битное целое):
    - Максимальное значение: 2^31-1 = 2147483647
    - При переполнении происходит "wrap-around" (переполнение с отрицательным результатом)
    
    2. Для чисел с плавающей точкой (float64):
    - Максимальное значение: ~1.8e308
    - Добавление к max_float приводит к:
        - 0.0 при малых приращениях (потеря точности)
        - inf при двойном max_float (положительная бесконечность)

    3. Отличия от целочисленной арифметики Python:
    - Стандартные int Python не имеют жестких ограничений
    - NumPy использует фиксированное количество бит для хранения

    References
    ----------
    .. [1] Официальная документация Python: https://docs.python.org/3/library/sys.html
    .. [2] NumPy reference manual: https://numpy.org/doc/stable/reference/
    .. [3] IEEE Standard for Floating-Point Arithmetic (IEEE 754)
    .. [4] Голуб Дж., Ван Лоун Ч. Матричные вычисления. М.: Мир, 1999.
    """
    print(f'переполнение')
    print(np.iinfo(np.int32).max)
    print(np.int32(np.iinfo(np.int32).max) + 1)
    print(sys.float_info.max)
    print(sys.float_info.max + 5 - sys.float_info.max)
    print(sys.float_info.max + sys.float_info.max)


def poterya_tochnosti():
    """
    Демонстрация потери точности при арифметических операциях с числами с плавающей точкой.

    Parameters
    ----------
    Нет входных параметров

    Returns
    -------
    None
        Функция только выводит информацию в консоль.

    Examples
    --------
    >>> poterya_tochnosti()
    потеря точности
    1e-09

    (В реальности возможен вывод 0.0 или 1e-09 в зависимости от реализации float в интерпретаторе)

    Notes
    -----
    1. Проблема возникает из-за ограниченной точности представления чисел с плавающей точкой (IEEE 754):
    - 64-битные числа (float64) имеют ~15-17 десятичных знаков точности
    - При вычитании близких чисел происходит потеря значащих разрядов (catastrophic cancellation)
    
    2. В примере:
    - 1.000_000_001 и 1.000_000_000 различаются на 1e-9
    - При представлении в формате float64 эти числа могут храниться с одинаковым приближением

    3. Для сравнения:
    - Целочисленная арифметика в Python не имеет этого ограничения
    - Для высокой точности можно использовать модуль decimal.Decimal

    References
    ----------
    .. [1] IEEE Standard for Floating-Point Arithmetic (IEEE 754)
    .. [2] Голуб Дж., Ван Лоун Ч. Матричные вычисления. М.: Мир, 1999.
    .. [3] Официальная документация Python по числам с плавающей точкой: https://docs.python.org/3/tutorial/floatingpoint.html
    .. [4] Higham, N. J. Accuracy and Stability of Numerical Algorithms. SIAM, 2002.
    """
    print(f'потеря точности')
    print(1.000_000_001 - 1.000_000_000)


def oshibka_okrugleniya():
    """
    Демонстрация ошибок округления при арифметических операциях с числами с плавающей точкой.

    Parameters
    ----------
    Нет входных параметров

    Returns
    -------
    None
        Функция только выводит информацию в консоль.

    Examples
    --------
    >>> oshibka_okrugleniya()
    ошибки округления
    False

    (Результат может варьироваться в зависимости от реализации float в интерпретаторе)

    Notes
    -----
    1. Проблема вызвана ограничениями стандарта IEEE 754 для чисел с плавающей точкой:
    - Числа 0.1 и 0.2 не могут быть точно представлены в двоичной системе
    - При сложении возникает накопление ошибки округления
    - Результат 0.1 + 0.2 ≈ 0.30000000000000004 (не равно 0.3)

    2. Подобные ошибки характерны для:
    - Все языков программирования, использующих IEEE 754
    - Операций с десятичными дробями, которые не являются степенью двойки
    - Сравнений на равенство с float числами

    3. Для точных вычислений:
    - Используйте модуль decimal.Decimal для финансовых расчетов
    - Применяйте сравнение с допуском (epsilon): abs(a - b) < 1e-9

    References
    ----------
    .. [1] IEEE Standard for Floating-Point Arithmetic (IEEE 754)
    .. [2] Голуб Дж., Ван Лоун Ч. Матричные вычисления. М.: Мир, 1999.
    .. [3] Официальная документация Python по числам с плавающей точкой: https://docs.python.org/3/tutorial/floatingpoint.html
    .. [4] Higham, N. J. Accuracy and Stability of Numerical Algorithms. SIAM, 2002.
    """
    print(f'ошибки округления')
    print(0.1 + 0.2 == 0.3)

    

def nakoplenie_oshibok():
    """
    Демонстрация накопления ошибок округления при многократном сложении чисел с плавающей точкой.

    Parameters
    ----------
    Нет входных параметров

    Returns
    -------
    None
        Функция только выводит информацию в консоль.

    Examples
    --------
    >>> nakoplenie_oshibok()
    накопление ошибок
    100000.0
    0.0

    (На самом деле возможен вывод вроде:
    100000.00000143294
    -1.43294e-06
    или другие незначительные отклонения от теоретического значения)

    Notes
    -----
    1. Проблема вызвана ограничениями стандарта IEEE 754:
    - Число 0.1 не может быть точно представлено в двоичной системе
    - Каждое сложение добавляет малую ошибку округления
    - При миллионе итераций эти ошибки кумулируются в значимую величину

    2. Особенности:
    - Даже при теоретическом результате 100_000.0 (1_000_000 * 0.1) 
        фактический результат может отличаться
    - Ошибка зависит от порядка операций и реализации float в интерпретаторе

    3. Для сравнения:
    - При использовании целочисленной арифметики (например, операций с копейками) 
        такой проблемы нет
    - Для финансовых расчетов рекомендуется использовать модуль decimal.Decimal
    - Для научных вычислений применяют алгоритмы компенсированного суммирования (алгоритм Кэхэна)

    References
    ----------
    .. [1] IEEE Standard for Floating-Point Arithmetic (IEEE 754)
    .. [2] Голуб Дж., Ван Лоун Ч. Матричные вычисления. М.: Мир, 1999.
    .. [3] Официальная документация Python по числам с плавающей точкой: https://docs.python.org/3/tutorial/floatingpoint.html
    .. [4] Higham, N. J. Accuracy and Stability of Numerical Algorithms. SIAM, 2002.
    """
    print(f'накопление ошибок')
    x = 0
    true_init = 100_000.0
    for _ in range(1_000_000):
      x+=0.1
    print(x)
    print(true_init-x)




def poterya_znachimosti():
    """
    Демонстрация потери значимости при вычислении экспоненты малых чисел.

    Parameters
    ----------
    Нет входных параметров

    Returns
    -------
    None
        Функция только выводит информацию в консоль.

    Examples
    --------
    >>> poterya_znachimosti()
    потеря значимости
    1.0000000827.40371e-10

    (Фактический результат может варьироваться в зависимости от точности вычислений NumPy)

    Notes
    -----
    1. Проблема вызвана комбинацией:
    - Представление чисел с плавающей точкой в формате IEEE 754 (ограниченная точность)
    - Вычитание близких значений (1 и exp(1e-10) ≈ 1.0000000001)

    2. Для малых x известно, что:
    exp(x) ≈ 1 + x + x²/2! + x³/3! + ...
    При x=1e-10, теоретическое значение exp(x)-1 ≈ 1e-10

    3. Ошибки проявляются как:
    - Потеря относительной точности из-за вычитания
    - Округление промежуточных результатов
    - Ограниченное количество значащих десятичных разрядов (15-17 для float64)

    4. Альтернативные подходы:
    - Использование специальной функции `np.expm1(x)` для точного вычисления exp(x)-1
    - Разложение в ряд Тейлора при малых x
    - Использование библиотек с произвольной точностью

    References
    ----------
    .. [1] IEEE Standard for Floating-Point Arithmetic (IEEE 754)
    .. [2] Голуб Дж., Ван Лоун Ч. Матричные вычисления. М.: Мир, 1999.
    .. [3] Официальная документация NumPy: https://numpy.org/doc/
    .. [4] Higham, N. J. Accuracy and Stability of Numerical Algorithms. SIAM, 2002.
    """
    print(f'потеря значимости')
    print(np.exp(1e-10) - 1)





def summirovanie_po_Kohanu(numbers):
    """
    Алгоритм суммирования по Кохану для минимизации ошибок округления при сложении чисел с плавающей точкой.
    Parameters
    ----------
    numbers : list or ndarray
        Последовательность чисел с плавающей точкой или целых чисел, которые необходимо просуммировать. 
        Пример: [1.0, 2.0, 3.0]
    Returns
    -------
    float
        Сумма всех чисел в последовательности с учетом компенсации ошибок округления по алгоритму Кохана.
    Examples
    --------
    >>> summirovanie_po_Kohanu([1.0, 2.0, 3.0])
    6.0
    >>> summirovanie_po_Kohanu(np.arange(1, 10**5))
    4999950000.0
    Notes
    -----
    Алгоритм Кохана позволяет сохранить численную точность при суммировании большого количества чисел с плавающей точкой, 
    что особенно важно при операциях с большими объемами данных или в научных вычислениях. 
    Метод использует дополнительную переменную для хранения накопленной ошибки округления и корректирует итоговую сумму на её значение.
    References
    ----------
    .. [1] Кахан В. (1965). "Further remarks on reducing truncation errors." Numerische Mathematik 7 (1): 488.
    .. [2] Higham, N. J. (2002). Accuracy and Stability of Numerical Algorithms (2nd ed.). SIAM.
    .. [3] Wikipedia: https://ru.wikipedia.org/wiki/Суммирование_по_Кохану
    """
    # Алгоритм суммирования по Кохану для минимизации ошибок округления
    def kahan_sum(numbers):
        total = 0.0
        correction = 0.0
        for num in numbers:
            y = num - correction
            temp = total + y
            correction = (temp - total) - y
            total = temp
        return total
    return kahan_sum(numbers)

BASE = [perepolnenie,poterya_tochnosti,oshibka_okrugleniya,nakoplenie_oshibok,poterya_znachimosti,summirovanie_po_Kohanu]