Загрузка данных


from struct import pack, unpack

def to_binary_ieee754(value: float) -> str:
    """ Конвертирует float в строку из 64 бит и разбивает её на компоненты: Знак (1) | Экспонента (11) | Мантисса (52) """
    # Получаем сырые байты и переводим в 64-битную строку
    raw_bytes = pack(">d", value)
    int_from_float = unpack(">Q", raw_bytes)[0]
    bitstring = f"{int_from_float:064b}"
    sign = bitstring[0:1]
    exp = bitstring[1:12]
    significand = bitstring[12:64]
    return f"{sign} | {exp} | {significand}"

a = 0.1
b = 0.2
sum_ab = a + b

print("Формат вывода битов: Знак (1 бит) | Экспонента (11 бит) | Мантисса (52 бита)")
print("-" * 86)
print(f"a (0.1)  = {to_binary_ieee754(a)}")
print(f"b (0.2)  = {to_binary_ieee754(b)}")
print(f"a + b    = {to_binary_ieee754(sum_ab)}")
# Для сравнения выведем честное число 0.3
print(f"c (0.3)  = {to_binary_ieee754(0.3)}")
print("-" * 86)
print(f"Значение a + b в Python: {sum_ab:.20f}")
print(f"Значение c (0.3) в Python: {0.3:.20f}")
print("-" * 86)

print("\nОПРОВЕРЖЕНИЕ АКСИОМ IEEE 754")

# 1. АССОЦИАТИВНОСТЬ (Сложение)
# (x + y) + z != x + (y + z) из-за разности порядков слагаемых
x1, y1, z1 = 1e16, -1e16, 1.0
res1_1 = (x1 + y1) + z1
res1_2 = x1 + (y1 + z1)
print("\n1. Ассоциативность сложения: (1e16 + -1e16) + 1.0 != 1e16 + (-1e16 + 1.0)")
print(f"(x + y) + z = {res1_1} -> {to_binary_ieee754(res1_1)}")
print(f"x + (y + z) = {res1_2} -> {to_binary_ieee754(res1_2)}")

# 2. АССОЦИАТИВНОСТЬ (Умножение)
# (x * y) * z != x * (y * z) из-за промежуточного переполнения в бесконечность
x2, y2, z2 = 1e200, 1e200, 1e-200
res2_1 = (x2 * y2) * z2
res2_2 = x2 * (y2 * z2)
print("\n2. Ассоциативность умножения: (1e200 * 1e200) * 1e-200 != 1e200 * (1e200 * 1e-200)")
print(f"(x * y) * z = {res2_1} -> {to_binary_ieee754(res2_1)}")
print(f"x + (y + z) = {res2_2} -> {to_binary_ieee754(res2_2)}")

# 3. ДИСТРИБУТИВНОСТЬ (потеря точности)
# x * (y + z) != x * y + x * z
x3, y3, z3 = 0.1, 0.2, 0.3
res3_1 = x3 * (y3 + z3)
res3_2 = x3 * y3 + x3 * z3
print("\n3. Дистрибутивность: 0.1 * (0.2 + 0.3) != 0.1 * 0.2 + 0.1 * 0.3")
print(f"x * (y + z) = {res3_1:.20f} -> {to_binary_ieee754(res3_1)}")
print(f"x*y + x*z   = {res3_2:.20f} -> {to_binary_ieee754(res3_2)}")

# 4. ДИСТРИБУТИВНОСТЬ (Переполнение vs Точный расчет)
# Разное поведение при генерации бесконечности
x4, y4, z4 = 2.0, 1e308, -1e308
res4_1 = x4 * (y4 + z4)
res4_2 = x4 * y4 + x4 * z4
print("\n4. Дистрибутивность с переполнением: 2.0 * (1e308 + -1e308) != 2.0 * 1e308 + 2.0 * -1e308")
print(f"x * (y + z) = {res4_1} -> {to_binary_ieee754(res4_1)}")
print(f"x*y + x*z   = {res4_2} -> {to_binary_ieee754(res4_2)}")

# 5. НАЛИЧИЕ ЕДИНСТВЕННОГО НУЛЯ (Существование -0.0)
# В IEEE 754 сосуществуют два нуля с разными битовыми масками
zero_plus = 0.0
zero_minus = -0.0
print("\n5. Наличие нуля (Неединственность битового представления): 0.0 == -0.0 математически, но биты разные")
print(f" +0.0 = {zero_plus} -> {to_binary_ieee754(zero_plus)}")
print(f" -0.0 = {zero_minus} -> {to_binary_ieee754(zero_minus)}")

# 6. НАЛИЧИЕ НУЛЯ (Свойства нейтрального элемента)
# x + 0 != x, если x является NaN (Not a Number)
nan_val = float('nan')
res6 = nan_val + 0.0
print("\n6. Наличие нуля (Нарушение нейтральности для NaN): NaN + 0.0 != NaN (логическое сравнение всегда False)")
print(f"NaN       -> {to_binary_ieee754(nan_val)}")
print(f"NaN + 0.0 -> {to_binary_ieee754(res6)}")
print(f"Проверка равенства (nan_val + 0.0 == nan_val): {res6 == nan_val}")

# 7. ПРОТИВОПОЛОЖНОЕ ЧИСЛО (Существование обратного по сложению)
# x + (-x) != 0 для бесконечности
inf_val = float('inf')
res7 = inf_val + (-inf_val)
print("\n7. Противоположное число: inf + (-inf) != 0.0")
print(f"inf + (-inf) = {res7} -> {to_binary_ieee754(res7)}")

# 8. КОММУТАТИВНОСТЬ (Сравнение с участием NaN)
# x + y == y + x по значению, но операции сравнения с NaN ломают рефлексивность и транзитивность коммутативности
x8 = float('nan')
y8 = 5.0
print("\n8. Коммутативность сравнения с NaN: NaN + 5.0 == 5.0 + NaN возвращает False, так как NaN ничему не равен")
print(f"NaN + 5.0 = {x8 + y8} -> {to_binary_ieee754(x8 + y8)}")
print(f"5.0 + NaN = {y8 + x8} -> {to_binary_ieee754(y8 + x8)}")
print(f"Равны ли результаты вычислений? {(x8 + y8) == (y8 + x8)}")

# 9. КОММУТАТИВНОСТЬ (Сложение знаков нуля)
x9 = 1e-200
y9 = 1e-200
res9 = x9 * y9
print("\n9. Нарушение аксиомы целостности поля (из-за потери значимости / Underflow): x * y == 0 при x != 0 и y != 0")
print(f"x (1e-200) = {x9} -> {to_binary_ieee754(x9)}")
print(f"x * y      = {res9} -> {to_binary_ieee754(res9)}")