new sistem
This commit is contained in:
118
app/src/pages/tabs/pentecostal_system9.py
Normal file
118
app/src/pages/tabs/pentecostal_system9.py
Normal file
@@ -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()
|
||||
237
app/src/pages/tabs/sedecim_calculeator8.py
Normal file
237
app/src/pages/tabs/sedecim_calculeator8.py
Normal file
@@ -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()
|
||||
Reference in New Issue
Block a user