diff --git a/app/src/pages/tabs/pentecostal_system9.py b/app/src/pages/tabs/pentecostal_system9.py new file mode 100644 index 0000000..f54c8fd --- /dev/null +++ b/app/src/pages/tabs/pentecostal_system9.py @@ -0,0 +1,118 @@ +from designer import right_column +import flet as ft + +class Button_binary_data(ft.CupertinoButton): + def __init__(self, text: str = "Двоичная система счисления"): + super().__init__( + bgcolor="#00000000", + disabled_bgcolor="#3A1E51", + text=text, + color="white", + on_click=self.test_data + ) + + def test_data(e, self): + md1=""" + Двоичная система счисления — это система, в которой используются только две цифры: 0 и 1. + Двои́чная систе́ма счисле́ния — позиционная система счисления с основанием 2. Благодаря непосредственной реализации в цифровых электронных схемах на логических вентилях, двоичная система используется практически во всех современных компьютерах и прочих вычислительных электронных устройствах. + + Компьютеры хранят отрицательные числа иначе, чем положительные, из-за особенностей двоичной системы и конструкции процессоров. Вот основные способы: + + 1. Прямой код (очень редко используется) + + Старший бит (самый левый) делает число отрицательным: + Например, для 8 бит: + 00010101 — это +21 + 10010101 — это -21 + Недостатки: две разные записи нуля (положительный и отрицательный), сложнее реализовать арифметику. + + 2. Обратный код (редко используется) + + Если число отрицательное, инвертируются все биты, кроме знакового: + +21: 00010101 + -21: 11101010 + Недостатки: две записи нуля, сложная арифметика. + + 3. Дополнительный код (почти всегда используется) + + Для отрицательного числа инвертируются все биты и прибавляется единица: + +21: 00010101 + -21: инвертируем: 11101010, прибавляем 1: 11101011 + Преимущества: только одна запись нуля, простая арифметика (сложение и вычитание одинаковы для положительных и отрицательных чисел). + + Почему люди пишут числа как "-10101" + + Запись -10101 — это просто привычный способ обозначения отрицательных чисел в десятичной или любой другой системе счисления. + В памяти компьютера знак не хранится отдельно, а закодирован в битах (обычно старший бит — знаковый). + Для человека запись с минусом интуитивно понятна, для компьютера — это набор битов, интерпретируемый по правилам (обычно дополнительного кода). + + Другие тонкости + + Знаковый и беззнаковый типы: + Например, в языке C/C++ есть int (знаковый) и unsigned int (беззнаковый). + Переполнение: + Если сумма двух больших положительных чисел выходит за пределы диапазона типа, возникает переполнение. + Диапазон значений: + В 8 битах: + беззнаковый: 0..255 + знаковый (доп. код): -128..127 + + Пример (8 бит, дополнительный код) + + +5: 00000101 + -5: инвертируем: 11111010, прибавляем 1: 11111011 + Сложение: 00000101 + 11111011 = 00000000 (0), перенос игнорируется + + Мантиса, запятая и хранение дробных чисел + + Мантиса — это дробная часть числа в позиционной системе. В двоичной мантиса хранится как последовательность битов, где k-й бит дробной части соответствует весу 2^{-k}. + + Запятая (разделитель) в человеческом вводе обозначает границу между целой частью и мантиссой. Пример: 101,101₂ = 1*2^2 + 0*2^1 + 1*2^0 + 1*2^{-1} + 0*2^{-2} + 1*2^{-3} = 5.625. + + В реальной памяти компьютера точка (запятая) обычно не хранится как символ. Существует два распространённых способа хранения дробных чисел: + - Fixed-point (fixed Q-format): число хранится как целое, представляющее значение scaled = round(x * 2^{f}), где f — количество бит дробной части. Таким образом все числа интерпретируются как scaled/2^{f}. + - Floating-point (IEEE-754): хранится знак, экспонента и мантисса; формат сложнее, даёт большой диапазон и нормализацию. + + В этом калькуляторе дроби вводятся через запятую и обрабатываются как обычные дробные значения (float) с фиксированной точностью при выводе (frac_precision бит). + + Практические рекомендации + + - Если хотите работать с отрицательными целыми в двоичной системе — вводите строку ровно N бит (например, 16). Старший бит будет определять знак. + - Для дробных значений используйте запятую и при необходимости ставьте знак '-' перед всем числом: -101,01. + - Помните про переполнение: при выводе целого результата в двоичной системе он должен помещаться в выбранную разрядность. + """ + + right_column.controls=[ ft.Container( + bgcolor="#55257D", + padding=ft.padding.all(10), + border_radius=10, + expand=True, + content=ft.Column( + scroll=ft.ScrollMode.AUTO, + expand=True, + horizontal_alignment=ft.CrossAxisAlignment.CENTER, + controls=[ + ft.Text(md1, size=16, color="white"), + ft.Text("Перевод из десятичной системы в двоичную:", size=16, color="white"), + ft.Container( + bgcolor="#000000", + content=ft.Image(src="./Система счисления 1.jpg", expand=True), + border_radius=10, + width=350, + height=300, + ), + ft.Text("Перевод обратно в десятичную систему:", size=16, color="white"), + ft.Container( + bgcolor="#000000", + content=ft.Image(src="./Система счисления 2.png", expand=True), + border_radius=10, + width=580, + height=300, + ), + ft.Text("Работа со знаком:", size=16, color="white"), + + ], + #width=600, + ) + )] + e.page.update() \ No newline at end of file diff --git a/app/src/pages/tabs/sedecim_calculeator8.py b/app/src/pages/tabs/sedecim_calculeator8.py new file mode 100644 index 0000000..bc4b952 --- /dev/null +++ b/app/src/pages/tabs/sedecim_calculeator8.py @@ -0,0 +1,237 @@ +from designer import right_column +import flet as ft + +class Button_binary_calculator(ft.CupertinoButton): + def __init__(self, text: str = "Двоичный калькулятор"): + self.result_left = ft.Text(value="0", size=30, width=300) + self.result_right = ft.Text(value="0", size=30, width=300) + self.decimal_left = ft.Text(value="(0₁₀)", size=14, color="#B0B0B0", width=300) + self.decimal_right = ft.Text(value="(0₁₀)", size=14, color="#B0B0B0", width=300) + + # Поля ввода для вычитания + self.input_left_1 = None + self.input_left_2 = None + + # Поля ввода для сложения + self.input_right_1 = None + self.input_right_2 = None + + # Количество бит для представления (по умолчанию 8) + self.bit_width = 16 + + super().__init__( + bgcolor="#00000000", + disabled_bgcolor="#3A1E51", + text=text, + color="white", + on_click=self.test_data + ) + + def to_twos_complement(self, num, bit_width): + """Преобразует число в дополнительный код""" + if num >= 0: + return format(num, f'0{bit_width}b') + else: + # Для отрицательных чисел используем дополнительный код + return format((1 << bit_width) + num, f'0{bit_width}b') + + def from_twos_complement(self, binary_str): + """Преобразует из дополнительного кода в десятичное число""" + bit_width = len(binary_str) + value = int(binary_str, 2) + + # Проверяем знаковый бит (старший бит) + if binary_str[0] == '1': + # Отрицательное число + value = value - (1 << bit_width) + + return value + + def validate_binary(self, value): + """Проверяет, является ли строка корректным двоичным числом""" + if not value: + return True + # Только 0 и 1 + return all(c in "01" for c in value) + + def calculate_subtraction(self, e): + try: + bin1 = self.input_left_1.value or "0" + bin2 = self.input_left_2.value or "0" + + # Проверка корректности двоичных чисел + if not self.validate_binary(bin1) or not self.validate_binary(bin2): + self.result_left.value = "Ошибка: неверный формат" + self.decimal_left.value = "" + self.result_left.update() + self.decimal_left.update() + return + + # Преобразуем двоичные числа в десятичные + + if len(bin1) > 0 and bin1[0] == '1' and len(bin1) >= 8: + num1 = self.from_twos_complement(bin1) + else: + num1 = int(bin1, 2) if bin1 else 0 + + if len(bin2) > 0 and bin2[0] == '1' and len(bin2) >= 8: + num2 = self.from_twos_complement(bin2) + else: + num2 = int(bin2, 2) if bin2 else 0 + + # Вычисляем результат + result = num1 - num2 + + # Преобразуем обратно в двоичный формат (дополнительный код) + binary_result = self.to_twos_complement(result, self.bit_width) + + self.result_left.value = binary_result + self.decimal_left.value = f"({result}₁₀)" + self.result_left.update() + self.decimal_left.update() + except ValueError as ex: + self.result_left.value = "Ошибка" + self.decimal_left.value = str(ex) + self.result_left.update() + self.decimal_left.update() + + def calculate_addition(self, e): + try: + bin1 = self.input_right_1.value or "0" + bin2 = self.input_right_2.value or "0" + + # Проверка корректности двоичных чисел + if not self.validate_binary(bin1) or not self.validate_binary(bin2): + self.result_right.value = "Ошибка: неверный формат" + self.decimal_right.value = "" + self.result_right.update() + self.decimal_right.update() + return + + # Преобразуем двоичные числа в десятичные + # Если введено в дополнительном коде - интерпретируем как дополнительный код + if len(bin1) > 0 and bin1[0] == '1' and len(bin1) >= 8: + num1 = self.from_twos_complement(bin1) + else: + num1 = int(bin1, 2) if bin1 else 0 + + if len(bin2) > 0 and bin2[0] == '1' and len(bin2) >= 8: + num2 = self.from_twos_complement(bin2) + else: + num2 = int(bin2, 2) if bin2 else 0 + + # Вычисляем результат + result = num1 + num2 + + # Преобразуем обратно в двоичный формат (дополнительный код) + binary_result = self.to_twos_complement(result, self.bit_width) + + self.result_right.value = binary_result + self.decimal_right.value = f"({result}₁₀)" + self.result_right.update() + self.decimal_right.update() + except ValueError as ex: + self.result_right.value = "Ошибка" + self.decimal_right.value = str(ex) + self.result_right.update() + self.decimal_right.update() + + def test_data(self, e): + # Создаем поля ввода с валидацией для двоичных чисел + self.input_left_1 = ft.TextField( + label="Двоичное число 1", + width=250, + text_align=ft.TextAlign.RIGHT, + value="0", + input_filter=ft.InputFilter(regex_string=r"^[01]*$"), # только 0 и 1 + hint_text="Например: 00001010 (10) или 11110110 (-10)" + ) + self.input_left_2 = ft.TextField( + label="Двоичное число 2", + width=250, + text_align=ft.TextAlign.RIGHT, + value="0", + input_filter=ft.InputFilter(regex_string=r"^[01]*$"), + hint_text="Например: 00000101 (5)" + ) + + self.input_right_1 = ft.TextField( + label="Двоичное число 1", + width=250, + text_align=ft.TextAlign.RIGHT, + value="0", + input_filter=ft.InputFilter(regex_string=r"^[01]*$"), + hint_text="Например: 00001010 (10)" + ) + self.input_right_2 = ft.TextField( + label="Двоичное число 2", + width=250, + text_align=ft.TextAlign.RIGHT, + value="0", + input_filter=ft.InputFilter(regex_string=r"^[01]*$"), + hint_text="Например: 00000101 (5)" + ) + + right_column.controls = [ft.Container( + bgcolor="#55257D", + padding=ft.padding.all(10), + border_radius=10, + expand=True, + content=ft.Column( + scroll=ft.ScrollMode.AUTO, + expand=True, + controls=[ + ft.Text("Двоичный калькулятор (дополнительный код)", size=20, color="white", weight=ft.FontWeight.BOLD), + ft.Text("Отрицательные числа в дополнительном коде (старший бит = 1)", size=11, color="#B0B0B0", italic=True), + ft.Text(f"Разрядность: {self.bit_width} бит. Диапазон: {-(1 << (self.bit_width-1))} .. {(1 << (self.bit_width-1))-1}", size=11, color="#B0B0B0"), + ft.Row( + expand=True, + alignment=ft.MainAxisAlignment.CENTER, + vertical_alignment=ft.CrossAxisAlignment.START, + controls=[ + ft.Column( + expand=True, + alignment=ft.MainAxisAlignment.CENTER, + horizontal_alignment=ft.CrossAxisAlignment.CENTER, + controls=[ + self.input_left_1, + ft.Text("——— Вычитание", size=12, color="white"), + self.input_left_2, + ft.Container( + content=ft.Column([ + self.result_left, + self.decimal_left + ], horizontal_alignment=ft.CrossAxisAlignment.CENTER), + bgcolor="#3A1E51", + padding=10, + border_radius=5, + ), + ft.CupertinoButton("=", on_click=self.calculate_subtraction) + ] + ), + ft.Column( + expand=True, + alignment=ft.MainAxisAlignment.CENTER, + horizontal_alignment=ft.CrossAxisAlignment.CENTER, + controls=[ + self.input_right_1, + ft.Text("—|— Сложение", size=12, color="white"), + self.input_right_2, + ft.Container( + content=ft.Column([ + self.result_right, + self.decimal_right + ], horizontal_alignment=ft.CrossAxisAlignment.CENTER), + bgcolor="#3A1E51", + padding=10, + border_radius=5, + ), + ft.CupertinoButton("=", on_click=self.calculate_addition) + ] + ) + ] + ) + ], + ) + )] + e.page.update() \ No newline at end of file