Определить, есть ли в записи числа цифра, равная среднему арифметическому остальных цифр - Assembler (223113)

Узнай цену своей работы

Формулировка задачи:

Задано целое беззнаковое число Х<65536. Определить, есть ли в записи числа цифра, равная среднему арифметическому остальных цифр? Входное значение - число без знака длиной в слово – должно вводиться с клавиатуры. Результат работы – найденная цифра или соответствующее сообщение - необходимо вывести на экран. Обмен информацией с пользователем организовать в виде специальных сообщений, каждое из которых следует размещать в отдельной строке экрана.

Решение задачи: «Определить, есть ли в записи числа цифра, равная среднему арифметическому остальных цифр»

textual
Листинг программы
  1. LOCALS
  2.  
  3. .model small
  4.  
  5. .stack 100h
  6.  
  7. .data
  8.         X               dw      ?
  9.  
  10.         Prompt          db      'Input X: ', '$'
  11.         Error01         db      'Input error number',0Dh, 0Ah, '$'
  12.         msgFoundDigit   db      'Found Digit: '
  13.         Digit           db      0
  14.                         db      0Dh, 0Ah, '$'
  15.         msgNotFound     db      'Not found', 0Dh, 0Ah, '$'
  16.         CrLf            db      0Dh, 0Ah, '$'
  17.  
  18.         kbdBuf          db      6, 0, 6 dup(?)
  19.  
  20. .code
  21.  
  22. main    proc
  23.         mov     ax,     @data
  24.         mov     ds,     ax
  25.  
  26.         lea     si,     X
  27.         lea     di,     Prompt
  28.         call    InputUInt16
  29.  
  30.         ;вычисление суммы всех цифр и их количества в числе
  31.         mov     ax,     X
  32.         mov     bx,     0       ;bx=SumDigits - сумма цифр
  33.         mov     cx,     0       ;cx=N - количество цифр
  34.         mov     di,     10
  35. @@CalcSum:
  36.         mov     dx,     0       ;ax=Digit - очередная цифра
  37.         div     di
  38.         add     bx,     dx
  39.         inc     cx
  40.         or      ax,     ax
  41.         jnz     @@CalcSum
  42.  
  43.         ;проверка каждой цифры на то, что она равна
  44.         ;среднему арифметическому остальных цифр
  45.         ;т.е. Digit*(N-1)==(SumDigits-Digit)
  46.         mov     ax,     X       ;ax=X
  47.         mov     di,     10
  48.         dec     cx              ;cx=N-1
  49.         mov     si,     0       ;количество найденных цифр
  50.         jcxz    @@Result        ;если всего одна цифра в числе, то искать нечего
  51. @@ForEachDigit:
  52.         mov     dx,     0
  53.         div     di
  54.         push    ax
  55.         push    bx
  56.         sub     bx,     dx      ;bx=SumDigits-Digit
  57.         mov     ax,     dx      ;ax=Digit*(N-1)
  58.         add     dl,     '0'     ;перед затиранием от операции умножения значения в dx
  59.         mov     Digit,  dl      ;сохраним очередную цифру в памяти в виде символа
  60.         mul     cx
  61.  
  62.         cmp     ax,     bx      ;Digit*(N-1)==(SumDigits-Digit) ?
  63.         jne     @@SkipShow
  64.         inc     si              ;признак - цифра была найдена
  65.         push    ax
  66.         push    dx
  67.         mov     ah,     09h
  68.         lea     dx,     msgFoundDigit
  69.         int     21h
  70.         pop     dx
  71.         pop     ax
  72. @@SkipShow:
  73.         pop     bx
  74.         pop     ax
  75.         or      ax,     ax
  76.         jnz     @@ForEachDigit
  77. @@Result:
  78.         cmp     si,     0
  79.         jnz     @@SkipMsg
  80.         mov     ah,     09h
  81.         lea     dx,     msgNotFound
  82.         int     21h
  83. @@SkipMsg:
  84.  
  85.         mov     ax,     4C00h
  86.         int     21h
  87. main    endp
  88. ;ввод числа с обработкой ошибок
  89. ; ds:si - адрес числа
  90. ; ds:di - адрес строки приглашения к вводу
  91. InputUInt16     proc
  92.         push    ax
  93.         push    bx
  94.         push    cx
  95.         push    dx
  96.         push    si
  97.         push    di
  98.  
  99. @@Input:
  100.         push    si
  101.         push    di
  102.         ; ввод числа с клавиатуры (строки)
  103.         mov     ah,     09h
  104.         mov     dx,     di
  105.         int     21h
  106.  
  107.         mov     ah,     0Ah
  108.         lea     dx,     [kbdBuf]
  109.         int     21h
  110.  
  111.         ; перевод строки (на новую строку)
  112.         mov     ah,     09h
  113.         lea     dx,     [CrLf]
  114.         int     21h
  115.  
  116.         pop     di
  117.         pop     si
  118.  
  119.         ; преобразование строки в число
  120.         push    si
  121.         push    di
  122.         mov     di,     si
  123.         lea     si,     kbdBuf+1
  124.         call    Str2Num
  125.         pop     di
  126.         pop     si
  127.  
  128.         ; проверка на ошибку
  129.         jnc     @@NoError
  130.  
  131.         ; если есть ошибка ввода - напечатать сообщение об ошибке
  132.         mov     ah,     09h
  133.         lea     dx,     Error01
  134.         int     21h
  135.         jmp     @@Input
  136.  
  137.         ; если нет ошибки ввода - напечатать число
  138. @@NoError:
  139.         pop     di
  140.         pop     si
  141.         pop     dx
  142.         pop     cx
  143.         pop     bx
  144.         pop     ax
  145.         ret
  146. InputUInt16     endp
  147.  
  148.  
  149. ; преобразования строки в число
  150. ; на входе:
  151. ; ds:[si] - строка с числом
  152. ; ds:[di] - адрес числа
  153. ; на выходе
  154. ; ds:[di] - число
  155. ; CY - флаг переноса (при ошибке - установлен, иначе - сброшен)
  156. Str2Num proc
  157.         push    ax
  158.         push    bx
  159.         push    cx
  160.         push    dx
  161.         push    ds
  162.         push    es
  163.  
  164.         push    ds
  165.         pop     es
  166.  
  167.         mov     cl, ds:[si]
  168.         xor     ch, ch
  169.  
  170.         inc     si
  171.  
  172.         mov     bx, 10
  173.         xor     ax, ax
  174.  
  175. @@Loop:
  176.         mul     bx         ; умножаем ax на 10 ( dx:ax=ax*bx )
  177.         mov     [di], ax   ; игнорируем старшее слово
  178.         cmp     dx, 0      ; проверяем, результат на переполнение
  179.         jnz     @@Error
  180.  
  181.         mov     al, [si]   ; Преобразуем следующий символ в число
  182.         cmp     al, '0'
  183.         jb      @@Error
  184.         cmp     al, '9'
  185.         ja      @@Error
  186.         sub     al, '0'
  187.         xor     ah, ah
  188.         add     ax, [di]
  189.         jc      @@Error    ; Если сумма больше 65535
  190.         inc     si
  191.  
  192.         loop    @@Loop
  193.  
  194.         mov     [di], ax
  195.         clc
  196.         pop     es
  197.         pop     ds
  198.         pop     dx
  199.         pop     cx
  200.         pop     bx
  201.         pop     ax
  202.         ret
  203. @@Error:
  204.         xor     ax, ax
  205.         mov     [di], ax
  206.         stc
  207.         pop     es
  208.         pop     ds
  209.         pop     dx
  210.         pop     cx
  211.         pop     bx
  212.         pop     ax
  213.         ret
  214. Str2Num endp
  215.  
  216. ; выводит число из регистра AX на экран
  217. ; входные данные:
  218. ; ax - число для отображения
  219. ; cx - система счисления (не больше 10)
  220. Show_AX proc
  221.         push    ax
  222.         push    bx
  223.         push    cx
  224.         push    dx
  225.         push    di
  226.  
  227.         mov     cx, 10          ; cx - основание системы счисления
  228.         xor     di, di          ; di - кол. цифр в числе
  229.  
  230. @@Conv:
  231.         xor     dx, dx
  232.         div     cx              ; dl = num mod 10
  233.         add     dl, '0'         ; перевод в символьный формат
  234.         inc     di
  235.         push    dx              ; складываем в стэк
  236.         or      ax, ax
  237.         jnz     @@Conv
  238.         ; выводим из стэка на экран
  239. @@Show:
  240.         pop     dx              ; dl = очередной символ
  241.         mov     ah, 2           ; ah - функция вывода символа на экран
  242.         int     21h
  243.         dec     di              ; повторяем пока di<>0
  244.         jnz     @@Show
  245.  
  246.         pop     di
  247.         pop     dx
  248.         pop     cx
  249.         pop     bx
  250.         pop     ax
  251.         ret
  252. Show_AX endp
  253.  
  254. end     main

Объяснение кода листинга программы

  1. Инициализация переменных:
    • X - двухбайтовая переменная для хранения введенного числа
    • Prompt - строка для приглашения к вводу
    • Error01 - строка для сообщения об ошибке при вводе числа
    • msgFoundDigit - строка для сообщения о найденной цифре
    • Digit - переменная для хранения текущей проверяемой цифры
    • msgNotFound - строка для сообщения о том, что цифра не найдена
    • CrLf - строка для вывода новой строки на экран
    • kbdBuf - массив для хранения вводимого числа с клавиатуры
  2. Ввод числа с клавиатуры и обработка ошибок в InputUInt16
  3. Вычисление суммы всех цифр и их количества в числе
  4. Проверка каждой цифры на то, что она равна среднему арифметическому остальных цифр
  5. Вывод сообщений о найденных или не найденных цифрах
  6. Завершение программы.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

13   голосов , оценка 4.077 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы