Простое умножение и деление крайне неточно - PullRequest
0 голосов
/ 14 апреля 2020

tldr: формула x / (1 * 1) вычитает сотни триллионов. почему?

Привет всем! Я довольно новичок в python и при создании шифратора сообщений python с нуля, (я знаю, есть более простые способы создания кодировщиков сообщений. Я просто делаю это для опыта и удовольствия) очень простые проблемы умножения и деления быть дико неточным. По сути, мой кодировщик работает путем преобразования всех символов в строке ввода в числа, а затем умножения числа на два отдельных пользовательских ключа. Я тестировал со всеми ключами, установленными в 1, и кодировка работает отлично; декодирование это проблема. Моя формула:

Кодировка:

String = String * Key1 * Key2     #Both keys are set to 1

Декодирование:

String = String / (Key1 * Key2)     #Again, both keys are set to 1, so in theory it should just spit the string back out.

При вводе 370190160220170180330190140310320 , я получаю 3701901602201701773912126133388 1014 *.

370190160220170180330190140310320

370190160220170177391212613337088

Так что формула, эквивалентная x / (1 * 1), по-видимому, означает вычитание, хотя многие квадриллионы. Что тут происходит? Как я уже сказал, я довольно новичок в python, поэтому решение этой проблемы может быть безумно простым, но я просто не могу понять это.

Ответы [ 2 ]

1 голос
/ 14 апреля 2020

float деление (/) не является произвольно точным. int деление (//), однако!

Попробуйте это:

assert 370190160220170180330190140310320 == 370190160220170180330190140310320 // 1
assert 370190160220170180330190140310320 != 370190160220170180330190140310320 / 1

Для того, что вы делаете, вы, вероятно, захотите использовать // и % вместо /!

0 голосов
/ 14 апреля 2020

Вам нужно использовать Decimal, чтобы точно соответствовать большим числам, и вам нужно изменить точность, чтобы она была больше значения по умолчанию, равного 28.

from decimal import Decimal
x = Decimal(370190160220170180330190140310320)
print(x == (x/(1*1))) # False
from decimal import Decimal, getcontext
getcontext().prec = 40
x = Decimal(370190160220170180330190140310320)
print(x == (x/(1*1))) # True
...