ЛР-2 / ЯП №2
.pdfВсего в языке программирования Python есть 8 типов данных: 1.int – целые числа;
2.float – числа с плавающей точкой;
3.complex – комплексные числа (числа вида a + b*i, где a и b – вещественные числа, а i – мнимая единица, т.е. число для которого выполняется i^2 = -1);
4.string – строки;
5.bool – логический тип; 6.list – списки;
7.tuple – кортежи; 8.dict – словари; 9.set – множества.
В данной работе использовался тип данных float, который отвечает за числа с плавающей точкой. Переменная такого типа может принимать значения от 2.2^-308 до 1.7^308. Переменные типа int как и в других языках могут принимать значения от -2 147 483 648 до 2 147 483 648.
11
Заключение
Входе выполнения лабораторной работы было произведено знакомство
сосновными ошибками, возникающими при обработке вещественных чисел, а также работа с ними на практике, рассчитаны относительные ошибки. А также составлены коды для примеров из методического материала и даны комментарии к ним.
12
Приложение А
(обязательное)
Листинг кода для лабораторной работы
from math import *
x = float(24730187341.24022006) y = x * float(10**-10)
c = x + y
z1 = x + float(10**-8)
z2 = x - float(10**-8) k = floor(x)
print(f'x = {x:.8f}')
print(f'y = x*10^-10 = {y:.18f}') print(f'c = x+y = {c:.18f}')
print(f'c1 = округлить c до 9 знаков = {round(c,9):.9f}') print(f'z+ = x+10^-8 = {z1:.15f}')
print(f'z- = x-10^-8 = {z2:.15f}') print(f'k = floor(x) = {k}') print('\n' + ' '*60)
print('ОШИБКА 1: ИСЧЕЗНОВЕНИЕ ОПЕРАНДА') print(' '*60)
print(f'x = {x:.8f}') print(f'z+ = {z1:.8f}') print(f"z- = {z2:.8f}") print('\n' + ' '*60)
print('ОШИБКА 2: УМНОЖЕНИЕ ОШИБКИ') print(' '*60)
m = y*(10**3)
n = y*(10**3)+0.000001 z = m*m
v = n*n
print(f'm = {m:.9f}') print(f'n = {n:.9f}') print(f'z = m*m = {z:.9e}') print(f'v = n*n = {v:.9e}') print('\n' + ' '*60)
print('ОШИБКА 3: ПОТЕРЯ ЗНАЧИМОСТИ') print(' '*60)
g = c h = x
print(f'g = {g:.8f}') print(f'h = {h:.8f}') print(f'g - h = {g - h:.8f}') print(f'y = {y:.8f}') print("\n" + " " * 60)
print("Представление чисел в памяти (IEEE 754)") import struct
def float_to_bits(f):
"""Преобразование float в битовое представление""" s = struct.pack('>d', f)
i = struct.unpack('>q', s)[0] return bin(i)[2:].zfill(64)
def print_float_bits(value, name): bits = float_to_bits(value) sign = bits[0]
exponent = bits[1:12] mantissa = bits[12:]
13
print(f"\n{name} = {value}") print(f" Биты: {bits}")
print(f" Знак: {sign} | Экспонента: {exponent} | Мантисса: {mantissa[:13]}...") x = 12345.678
small = 0.0000001 print_float_bits(x, "x")
print_float_bits(x + small, "x + small") print_float_bits(x, "x (снова)")
print(f"\nБиты x и x+small одинаковы? {float_to_bits(x) == float_to_bits(x + small)}") print('\n' + ' '*60)
print('МАШИННЫЙ ЭПСИЛОН')
# float (Python float = double precision) epsilon_float = 1.0
while 1.0 + epsilon_float / 2.0 > 1.0: epsilon_float /= 2.0
print(f"Машинный эпсилон (float64): {epsilon_float}") print(f"Теоретическое значение: {2**-52:.16e}")
#Проверка с помощью math.ulp print(f"math.ulp(1.0) = {ulp(1.0)}")
print(f"Разница между двумя числами float64: {ulp(1.0)-epsilon_float}") print('\n' + ' '*60)
print("Метод Кахана для точного суммирования") def kahan_sum(numbers):
s = 0.0
c = 0.0 # Поправка for num in numbers:
y = num - c t = s + y
c = (t - s) - y s = t
return s
#Создаем массив чисел
n = 1000000
numbers = [0.1234567] * n
#Обычная сумма simple_sum = 0.0 for num in numbers:
simple_sum += num
#Метод Кахана
kahan = kahan_sum(numbers) exact_sum = 0.1234567 * n print(f"Точная сумма: {exact_sum}") print(f"Обычная сумма: {simple_sum}") print(f"Метод Кахана: {kahan}")
print(f"Ошибка обычной суммы: {abs(exact_sum - simple_sum)}") print(f"Ошибка метода Кахана: {abs(exact_sum - kahan)}")
14
