from decimal import Decimal, getcontext

getcontext().prec = 50  # Устанавливаем точность для Decimal


# Функция для высокоточного сложения
def add_high_precision(a, b):
    k1_a, k2_a, t_a = a
    k1_b, k2_b, t_b = b

    # Выровняем порядки чисел, прежде чем их сложить
    if t_a > t_b:
        k1_b *= Decimal(10) ** (t_a - t_b)
        k2_b *= Decimal(10) ** (t_a - t_b)
        t_b = t_a
    elif t_a < t_b:
        k1_a *= Decimal(10) ** (t_b - t_a)
        k2_a *= Decimal(10) ** (t_b - t_a)
        t_a = t_b

    # Производим сложение мантисс каждого числа
    k1 = k1_a + k1_b
    k2 = k2_a + k2_b

    # Проверяем не вышли ли мы за предел точности
    if k2 >= 1:
        k1 += 1
        k2 -= 1

    return (k1, k2, t_a)


# Функция для высокоточного умножения
def mul_high_precision(a, b):
    k1_a, k2_a, t_a = a
    k1_b, k2_b, t_b = b

    # Каждая часть 'a' умножается на каждую часть 'b'
    c1 = k1_a * k1_b
    c2 = k1_a * k2_b + k2_a * k1_b
    c3 = k2_a * k2_b

    # Порядок 'c2' меньше, чем у 'c1', а 'c3' еще на один порядок меньше
    t = t_a + t_b

    # Складываем все части, следя за выходом за предел точности
    while c3 >= Decimal(10)(-getcontext().prec):
        c3 *= Decimal(10)
        t -= 1

    c2 += c3
    while c2 >= Decimal(10)(-getcontext().prec):
        c2 *= Decimal(10)
        t -= 1

    c1 += c2
    while c1 >= Decimal(10) ** (-getcontext().prec):
        c1 *= Decimal(10)
        t -= 1

    # Возвращаем только две части и порядок, так как c1 может быть больше 1
    return (c1, Decimal(0), t)


# Функция для вычисления скалярного произведения, использующая высокоточные операции
def scalar_product_high_precision(v1, v2):
    result = (Decimal(0), Decimal(0), 0)
    for a, b in zip(v1, v2):
        # Умножим и сложим результат с аккумулирующим значением
        result = add_high_precision(result, mul_high_precision(a, b))
    k1, k2, power = result
    return (k1 + k2) * Decimal(10) ** power


# Определение векторов для примера (используем Decimal и правильные степени)
v1 = [(Decimal('0.1234567') * Decimal(10) ** 3, Decimal(0), 0), (Decimal('0.7653241234') * Decimal(10) ** 6, Decimal(0), 0), (Decimal('0.45678903456789') * Decimal(10) ** 10, Decimal(0), 0)]
v2 = [(Decimal('0.45678904567') * Decimal(10) ** 5, Decimal(0), 0), (Decimal('0.7653241234') * Decimal(10) ** 1, Decimal(0), 0), (Decimal('0.4567895678767890987456789567803456789') * Decimal(10) ** 10, Decimal(0), 0)]

# Вычисление скалярного произведения с использованием высокоточной арифметики
high_prec_result = scalar_product_high_precision(v1, v2)
print("High precision result:", high_prec_result)

# Сравнение со стандартными вычислениями с плавающей точкой
standard_result = sum((a[0] + a[1]) * (b[0] + b[1]) for a, b in zip(v1, v2))
print("Standard floating - point result:", standard_result)


Traceback (most recent call last):
  File "C:\Users\User\PycharmProjects\lab2\main.py", line 80, in <module>
    high_prec_result = scalar_product_high_precision(v1, v2)
  File "C:\Users\User\PycharmProjects\lab2\main.py", line 70, in scalar_product_high_precision
    result = add_high_precision(result, mul_high_precision(a, b))
  File "C:\Users\User\PycharmProjects\lab2\main.py", line 47, in mul_high_precision
    while c3 >= Decimal(10)(-getcontext().prec):
TypeError: 'decimal.Decimal' object is not callable