Сложить 2 числа и только что получится
Перейти к содержимому

Сложить 2 числа и только что получится

  • автор:

Как сложить два числа из строки?

У меня есть переменная, где хранится строка number = «2+2» Как сделать так, чтобы python сложил эти 2 числа?

Отслеживать
3,149 2 2 золотых знака 11 11 серебряных знаков 36 36 бронзовых знаков
задан 8 окт 2023 в 10:41
Artuom Jdkd Artuom Jdkd
63 4 4 бронзовых знака

3 ответа 3

Сортировка: Сброс на вариант по умолчанию

number = eval(number) 

Функция eval() преобразует и вычисляет переданные ей в виде строки выражения.

Вообще, использование функций eval() и exec() чревато ошибками и проблемами безопасности. Подробнее здесь.

Отслеживать
ответ дан 8 окт 2023 в 10:52
2,337 2 2 золотых знака 9 9 серебряных знаков 30 30 бронзовых знаков

А можно вот так:

number = '2+2' print(sum(map(int, number.split('+')))) 

Притом это будет работать даже со строкой 2+2+2 .

Отслеживать
ответ дан 8 окт 2023 в 11:35
2,836 5 5 золотых знаков 9 9 серебряных знаков 28 28 бронзовых знаков

Да, eval() хороший метод, но возможны не очень хорошие вводы данных, когда вы будете работать с input() (типа команды удаления диска С), поэтому:

  1. Можно использовать условную конструкцию if :
number='2+2' if number.replace('*','').replace('+','').replace('-','').replace('/','').isdigit(): number=eval(number) print(f'Ответ: ') else: print('Ошибка: введено не число') 
  1. Использовать регулярки (регулярные выражения):
import re number='2x2' x=True number_split=re.split('[+*-//]', number) for i in number_split: if i.isdigit(): continue print('Ошибка: введено не число') x=False break if x: print(eval(number)) 

Python: сложить два числа — что может быть проще?

Не буду ходить вокруг да около и сразу начну с правильного решения:

(a, b) = input().split()
print(int(a) + int(b))

Давайте теперь откроем ленту комментариев и почитаем, с чем сталкиваются пользователи при ее решении:

Пользователь под ником Міша павлович спрашивает, почему его решение не работает:

a = input()
b = input()
print(int(a)+int(b))

Если внимательно посмотреть на условие задачи, то из него видно, что переменные A и B передаются в одной строке через пробел, тогда как функция input() считывает введенную строку целиком. Таким образом в переменную A попадает строка «3 8», а переменная B не считывается вовсе.

Другой пользователь под ником Hmann wmann предлагает свое решение, которое не проходит проверку:

x = input("number 1: ")
y = input("number 2: ")
z = int(x) + int(y)
print(z)

Здесь проблема в том, что строки input(«number 1: «) сначала выводят на печать строку number 1: , а потом считывают значение из потока ввода, таким образом засоряя поток вывода, в который по условию должна попасть только сумма.

Еще одна потенциальная ошибка — это считать строку, разделить по символу пробела на 2 части и забыть, что результат разбиения имеет строковое значение, а не числовое. А оператор сложения примененный к строковым переменным имеет значение конкатенации.

>>> 3 + 8 11 >>> '3' + '8' '38'

В нашем примере для разбиения строк используется функция split() :

def parse_numbers_v1(input_str: str) -> (int, int): 
(a, b) = input_str.split()
return int(a), int(b)
assert parse_numbers_v1("12 34") == (12, 34)
assert parse_numbers_v1("0 88") == (0, 88)
assert parse_numbers_v1("1056 4") == (1056, 4)

Давайте для тренировки попробуем представить, что такой функции у нас нет.

В этом случае, нам нужно будет найти в строке символ пробела с помощью метода find и, зная местонахождение пробельного символа, разделить строку на до и после. В языке Python это удобно делать, указывая значения начала и конца подстроки в квадратных скобках string[begin:end] . В случае отсутствие чисел begin и end будет подставлено начало и конец строки соответственно:

def parse_numbers_v2(input_str: str) -> (int, int): 
space_pos = input_str.find(' ')
return int(input_str[:space_pos]), int(input_str[space_pos + 1:])

Как насчет усложнить задачу? Представим, что функция поиска по строке нам недоступна, также как и функция приведения строки к числу int() . В том случае, если число одно, нам нужно просто считывать символы строки по порядку от начала к концу, на каждом символе увеличивая чисто в 10 раз и прибавляя новый считанный символ, приведенный к числу по его номеру в таблице кодировки:

def parse_number(input_str: str) -> (int, int): 
number = 0
for char in input_str:
number = number * 10 + ord(char) - 48
return number
assert parse_number('123') == 123
assert parse_number('0') == 0
assert parse_number('1066') == 1066

Для считывания двух символов логику нужно будет немного усложнить, добавив проверку на тип символа:

def parse_numbers_v3(input_str: str) -> (int, int): 
number = 0
first_number = 0
for char in input_str:
if '0' '9':
number = number * 10 + ord(char) - 48
else:
first_number = number
number = 0
return first_number, number

Здесь мы уже работаем с символами в строке напрямую без каких-либо вспомогательных функций. Ускорило ли это работу? Давайте сравним три реализации функции parse_numbers по скорости их работы.

В качестве тестовых значений сгенерируем миллион строк с двумя числами, разделенными символами пробела:

from random import randint
test_input = []
for i in range(1_000_000):
test_input.append(str(randint(0, 10_000_000)) + ' ' + str(randint(0, 10_000_000)))

И разделим их с помощью трех вариантов функции, измерив скорость работы каждой из них:

begin_time = perf_counter()
for i in test_input:
parse_numbers_v1(i)
v1_time = perf_counter() - begin_time
begin_time = perf_counter()
for i in test_input:
parse_numbers_v2(i)
v2_time = perf_counter() - begin_time
begin_time = perf_counter()
for i in test_input:
parse_numbers_v3(i)
v3_time = perf_counter() - begin_time
print('First function:', v1_time)
print('Second function:', v2_time)
print('Third function:', v3_time)

Результат работы вполне наглядный:

First function: 0.7454843000000002 Second function: 0.9237659000000003 Third function: 3.8371637000000005

Как видим уход от стандартный функций языка, таких как split() и int() не только не дал роста производительности, но и существенно замедлил работу алгоритма.

Это хорошая демонстрация того, что зачастую лучше использовать стандартные возможности языка, чем писать ту же функциональность заново и по-своему. Стандартные функции обычно максимально оптимизированы разработчиками языка и едва ли имеет смысл соревноваться с ними в производительности, тем более используя тот же язык программирования.

Как сложить два числа в Ассемблере

В Контакте Ютуб Почта

Складывать числа в ассемблере не так уж и сложно. В подавляющем большинстве случаев это делается с помощью команды ADD. Но в любой задаче, даже самой простой, могут встретиться неожиданности, которые не может предусмотреть новичок в силу того, что не имеет достаточного опыта и знаний. Поэтому, несмотря на то, что в описании инструкции ADD всё достаточно понятно, я решил написать небольшую статью с примерами.

Итак, первое, что нам надо помнить — это размер числа. Если мы складываем два числа, то размер результата может быть больше, чем размер регистра, в который помещается результат.

Второе — мы можем складывать и отрицательные числа. Следовательно, и результат может быть отрицательным.

И да — сложение положительного и отрицательного чисел — это, по сути, вычитание одного числа из другого. Хотя для вычитания в ассемблере есть команда SUB.

Команда ADD существует с незапамятных времён — ещё с процессора 8086. Поэтому она поддерживается и всеми последующими процессорами Интел и совместимыми.

Простейший пример использования:

MOV AL, 3 ADD AL, 2 ; AL = 3 + 2 = 5

Здесь мы сначала записали число 3 в регистр AL, а затем применили команду ADD для сложения числа в AL с числом 2. Результат записывается в нашем случае в AL. И там после выполнения команды будет число 5.

Но складывать можно не только значение в регистре с числом. Но и, например, значения двух регистров:

MOV BX, 7 MOV AX, 2 ADD AX, BX ; AX = 7 + 2 = 9

Также вместо регистров можно использовать память:

MOV [110h], 3 ADD [110h], 2 ; По адресу [110h] теперь хранится 5 MOV AL, 1 ADD AL, [110h] ; AL = 6

При работе с памятью, конечно, надо понимать, что находится по данному адресу и к каким последствиям может привести прямое обращение к памяти и изменение её содержимого. В данном примере на это мы внимания не обращаем. Это просто пример.

Складывать можно не только константы, регистры и память, но и переменные:

ADD BL, MyVar ADD MyVar, 3

Не знаю, во всех ли ассемблерах это будет работать. Но в эмуляторе точно работает. Причём оба варианта. То есть можно записывать результат как в регистр, так и в переменную.

Есть ещё такая тема, как сложение с переносом. Но в этой статье рассматривать её не будет. Больше сведений об этом можно найти здесь.

И есть ещё такая вещь, как BCD-значения. Инструкции для работы с такими значениями: AAA, AAD, AAS, AAM.

На этом пока всё. Подключайтесь к группе Основы программирования в Телеграм, или к другим каналам (ссылки ниже), чтобы ничего не пропустить.

Учим компьютер складывать числа любой длины

Если в JavaScript сложить два небольших числа, компьютер легко с этим справится. Но если попросить его сложить числа, например, на 500 знаков, то будет ошибка: язык не рассчитан на такие огромные числа.

А вот человеку неважно, какой длины числа складывать: хоть 100 знаков, хоть 500, хоть тысяча. Если есть лист бумаги, ручка и достаточно времени, человек сложит любые числа. Сегодня мы научим компьютер тоже так делать.

Чтобы было понятнее, запустите этот JavaScript-код в консоли браузера и посмотрите на ошибку:

var a = 7983577598237509273059298347502798357759823750927305929834750279835345234952394529345238721948571908745082345234523452345234523452934570293452345234577598237509273052345345345929834750279835775982375092730592983475079835775982375092730592983475027983577598237509273059298347502798353452349523945293452387219485719087450823452345234523452345234529345702934523452345775982375092730523453453459298347502798357759823750927305929834750; var b = 92385482375823598236459872635923854823758235982364598726359238548237582323412345293457293745092734509273405972923453872430918723545983452435729752934579238475928345245734523645987268983592385482375823598236459872639; var c; c = a+b; console.log(c);

Как работает сложение в столбик

Вы и так это знаете, но нам нужно для будущего алгоритма:

  1. Записываем сначала число подлиннее, а под ним — число покороче (или просто друг под другом, если они одной длины).
  2. Записывать надо с выравниванием по правой стороне.
  3. Складываем числа по разрядам по очереди: единицы с единицами, десятки с десятками и так далее.
  4. Если после разрядного сложения получилось двузначное число, единица добавляется в следующий разряд и учитывается при следующем сложении
  5. Так шаг за шагом мы перебираем все разряды, и у нас в результате получается сумма.

Даже если у нас тысяча разрядов, всё, что мы делаем на каждом шаге, — это складываем два числа от 0 до 9 и переносим единицу, если она появилась.

Простой пример сложения в столбик с переносом единицы:

Учим компьютер складывать числа любой длины

Почему компьютеру сложно работать с такими длинными числами и как это исправить

Всё дело в размере памяти, которую компьютер выделяет для переменной. Если это не специальный математический язык для обработки огромных чисел, то обычно на целое число выделяется до 8 байт. Этого хватает для большинства бытовых задач, но для экстремально больших чисел этого мало — нужны специальные библиотеки.

Лайфхак: работать с числами как со строками

Мы не будем использовать библиотеки, а пойдём другим путем: мы будем представлять число не как число, а как строку, состоящую из цифр. У строк нет таких ограничений, как у чисел: строки могут быть любой длины. Если мы научимся работать с этими строками как будто это числа, то сможем складывать что угодно любого размера.

Вот такое мы и будем делать для JavaScript.

Что делаем

Мы напишем на JavaScript код, который будет запрашивать у пользователя два целых положительных числа и складывать их. Логика будет такая:

  1. Просим ввести числа, но на самом деле мы их получим в виде строк.
  2. Сразу проверяем, нет ли в строке чего-то кроме цифр. Если есть — говорим, что это не число, и останавливаемся.
  3. Перебираем все разряды справа налево и складываем числа попарно и результат добавляем к строке с общим результатом.
  4. Если в результате такого мини-сложения получилось число больше 10 — переносим единицу в следующий разряд.
  5. Делаем так до тех пор, пока не закончатся разряды в числах.

В итоге мы получим строку с результатом сложения — это и будет наш ответ.

Запрашиваем строки и проверяем, числа это или нет

В самом начале нам нужно просто получить от пользователя две строки и проверить, нет ли там лишних символов кроме цифр. Для такой проверки напишем короткую функцию, в основе которой будет лежать такая команда:

isNaN() — она пробует перевести в число ту строку, которая стоит в скобках.

Если не получилось перевести, то команда возвращает true , а если получилось — false . Так мы проверим каждую строку, и, если в какой-то из них не только числа, — останавливаем скрипт и выводим ошибку.

Теперь про остановку скрипта. Один из приёмов, чтобы остановить скрипт в любом месте, — сгенерировать ошибку вручную. Это можно сделать так:

throw new Error(‘Текст ошибки’);

Как только скрипт встречает такое, он выбрасывает текст ошибки в консоль и останавливается:

Учим компьютер складывать числа любой длины

Запишем всё это на JavaScript:

// проверка, это число или нет function isNumber(s) < // по умолчанию считаем, что в функцию передали число flag = true; // если это пустая строка, то возвращаем false — признак того, что это не число if (s.length = 0) // раз дошли досюда, то строка не пустая и можно проверить все символы подряд for (let i = 0; i < s.length; i++) < // переводим символ в число и смотрим, будет ли ошибка // если ошибка есть — помечаем, что это не число if (isNaN(s[i]) == true) ; > // возвращаем результат обработки, число это или нет return(flag) > // запрашиваем первое var num1 = prompt("Введите первое слагаемое"); // проверяем, число это или нет if (!isNumber(num1)) < // если нет — выводим сообщение alert('Это не число'); // останавливаем программу с ошибкой throw new Error('Первое слагаемое — не число'); >// то же самое делаем со вторым числом var num2 = prompt("Введите второе слагаемое"); if (!isNumber(num2))

Выравниваем числа по длине

Чтобы нам было удобнее складывать в столбик, пойдём на такую хитрость: в то число, в котором меньше символов, мы добавим нули спереди. Они не изменят конечный результат, но с ними алгоритм получится гораздо проще. А если по длине числа одинаковые, то пусть так и остаётся.

// делаем числа одной длины, чтобы удобно было складывать // если второе длиннее первого if (num1.length < num2.length) < // то получаем разницу в длине чисел var diff = num2.length - num1.length // и добавляем впереди первого числа столько же нулей for (let i = 0; i < diff; i++) < num1 = '0' + num1; >// то же самое — если первое длиннее второго > else if (num1.length > num2.length) < var diff = num1.length - num2.length for (let i = 0; i < diff; i++) < num2 = '0' + num2; >> 

Складываем разряды

Вспомогательная штука, которая нам ещё понадобится, — функция сложения двух чисел. Её особенность в том, что туда попадают только разрядные числа — от 0 до 9. Ещё туда может попасть дополнительная единица при переносе разряда. Но в любом случае это очень маленькие числа, с которыми компьютер гарантированно справится.

Особенность функции в том, что она и на вход получает две строки, и на выходе тоже возвращает строку, а не числа. Если про это забыть и вернуть просто результат в виде числа, то придётся это обрабатывать отдельно в основном алгоритме, а это неэффективно.

// складываем два числа, которые на самом деле — строки function plus(a,b) < // тут будет результат var result =''; // переводим строки в числа x = parseInt(a); y = parseInt(b); // получаем результат result += x+y; // и возвращаем ответ в виде строки return(String(result)); >

Основной алгоритм

Мы сделали всю предварительную работу:

  • получили числа от пользователя;
  • убедились в том, что это числа;
  • сделали их одинаковой длины;
  • научились складывать разряды.

Теперь сделаем главное: научим компьютер складывать в столбик. Если при сложении разрядов получается число от 0 до 9, то всё просто: мы приписываем его к результату и идём к следующей паре разрядов. Но если мы складываем, например, 9 и 3, то получим двузначное число и единицу надо будет переносить в следующий разряд. Обработка такого переноса — самое сложное место в этом алгоритме.

Чтобы обработать разрядный перенос, мы заведём отдельную переменную. Как только у нас появляется перенос, мы устанавливаем флаг и по нему обрабатываем этот перенос. Читайте комментарии, чтобы разобраться в алгоритме:

// складываем любые два целых числа function bigplus(a,b) < // признак переноса var carry = false; // тут будет наш результат var summ = ''; // переменная для промежуточных вычислений var temp = ''; // число, которое добавится к результату var digit; // вспомогательная переменная, используем для складывания перенесённой единицы var plusOne = ''; // перебираем все символы в числах по очереди for (let i = 0; i < b.length; i++) < // если нужно перенести единицу в следующий разряд if (carry) < // добавляем её к следующему разряду в первом числе plusOne = plus(a[a.length -1 - i],'1'); // и складываем два числа уже с учётом переноса temp = plus(plusOne, b[b.length -1 - i]); // если единицу переносить не нужно >else < // то просто складываем два числа temp = plus(a[a.length -1 - i], b[b.length -1 - i]); >// если после сложения получилось однозначное число if (temp.length == 1) < // просто добавляем его к результату summ = temp + summ; // и переноса нет carry = false; // если число двузначное >else < // помечаем, что будет перенос, потому что получилось больше 10 carry = true; // получаем единицы, например, если у нас получилось 12, то берём оттуда 2 digit = temp[1]; // и добавляем эти единицы к результатам summ = digit + summ; // >> // после всего цикла обрабатываем последний перенос, если он получился if (carry) < // просто приписываем единицу к результату summ = '1' + summ; >// возвращаем результат return(summ); >

Считаем любую сумму

У нас есть все кирпичики программы. Собираем их в нужном порядке и получаем готовый скрипт. Чтобы проверить, работает он или нет, скормим ему длинные числа из самого начала статьи, где JavaScript сразу сломался:

Учим компьютер складывать числа любой длины

Готовый скрипт

// проверка, это число или нет function isNumber(s) < // по умолчанию считаем, что в функцию передали число flag = true; // если это пустая строка, то возвращаем false — признак того, что это не число if (s.length = 0) // раз дошли досюда, то строка не пустая и можно проверить все символы подряд for (let i = 0; i < s.length; i++) < // переводим символ в число и смотрим, будет ли ошибка // если ошибка есть — помечаем, что это не число if (isNaN(s[i]) == true) ; > // возвращаем результат обработки, число это или нет return(flag) > // складываем два числа, которые на самом деле — строки function plus(a,b) < // тут будет результат var result =''; // переводим строки в числа x = parseInt(a); y = parseInt(b); // получаем результат result += x+y; // и возвращаем ответ в виде строки return(String(result)); >// складываем любые два целых числа function bigplus(a,b) < // признак переноса var carry = false; // тут будет наш результат var summ = ''; // переменная для промежуточных вычислений var temp = ''; // число, которое добавится к результату var digit; // вспомогательная переменная, используем для складывания перенесённой единицы var plusOne = ''; // перебираем все символы в числах по очереди for (let i = 0; i < b.length; i++) < // если нужно перенести единицу в следующий разряд if (carry) < // добавляем её к следующему разряду в первом числе plusOne = plus(a[a.length -1 - i],'1'); // и складываем два числа уже с учётом переноса temp = plus(plusOne, b[b.length -1 - i]); // если единицу переносить не нужно >else < // то просто складываем два числа temp = plus(a[a.length -1 - i], b[b.length -1 - i]); >// если после сложения получилось однозначное число if (temp.length == 1) < // просто добавляем его к результату summ = temp + summ; // и переноса нет carry = false; // если число двузначное >else < // помечаем, что будет перенос, потому что получилось больше 10 carry = true; // получаем единицы, например, если у нас получилось 12, то берём оттуда 2 digit = temp[1]; // и добавляем эти единицы к результатам summ = digit + summ; // >> // после всего цикла обрабатываем последний перенос, если он получился if (carry) < // просто приписываем единицу к результату summ = '1' + summ; >// возвращаем результат return(summ); > // запрашиваем первое var num1 = prompt("Введите первое слагаемое"); // проверяем, число это или нет if (!isNumber(num1)) < // если нет — выводим сообщение alert('Это не число'); // останавливаем программу с ошибкой throw new Error('Первое слагаемое — не число'); >// то же самое делаем со вторым числом var num2 = prompt("Введите второе слагаемое"); if (!isNumber(num2)) < alert('Это не число'); throw new Error('Второе слагаемое — не число'); >// делаем числа одной длины, чтобы удобно было складывать // если второе длиннее первого if (num1.length < num2.length) < // то получаем разницу в длине чисел var diff = num2.length - num1.length // и добавляем впереди первого числа столько же нулей for (let i = 0; i < diff; i++) < num1 = '0' + num1; >// то же самое — если первое длиннее второго > else if (num1.length > num2.length) < var diff = num1.length - num2.length for (let i = 0; i < diff; i++) < num2 = '0' + num2; >> // считаем сумму и выводим результат alert(bigplus(num1,num2));

Получите ИТ-профессию

В «Яндекс Практикуме» можно стать разработчиком, тестировщиком, аналитиком и менеджером цифровых продуктов. Первая часть обучения всегда бесплатная, чтобы попробовать и найти то, что вам по душе. Дальше — программы трудоустройства.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *