Форум программистов, компьютерный форум, киберфорум
Assembler: Windows/protected mode
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/7: Рейтинг темы: голосов - 7, средняя оценка - 5.00
0 / 0 / 0
Регистрация: 23.11.2016
Сообщений: 30
1

Найти все трёхзначные числа, большие квадрата суммы своих цифр. Исправить код

30.04.2017, 21:24. Показов 1432. Ответов 15
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
//Найти все трёхзначные числа, большие квадрата суммы своих цифр
#include<iostream>
using namespace std;
int main()
{
    setlocale(LC_ALL, ".1251");
    int b = 100, border=1000, num, sum=0, ten=10, tmp;             //jge- если больше или равно
    _asm
    {
    
        //mov ebx, b
        mov ecx, b
        START : cmp ecx, border     //проверка, если уже вышли за границы
             jge END  
             
 
       POINT1:
            mov edx, 0
            mov eax, b
            cdq
            div ten
            mov eax, edx//; цифра
            add sum, eax
 
            //ml :
            mov eax, b
            cdq
            div ten
            mov b, eax
            cmp b, 0
            jne POINT1
            mov eax, sum
            mul eax     //возводим в квадрат
            mov num, eax
            cmp ecx, num
            mov tmp, ecx         
             jg PRINT    //если наше число больше, то выводит    
        PRINT : 
    }
    cout << tmp << endl;
    _asm
    {
        inc ecx
        jmp START 
        END:
    }
 
    return 0;
 
    }
Программа выводит только число 100. Может быть не заходит во вторую ассемблерную вставку и тупо не увеличивает число на 1? Прога с нахождением квадрата суммы цифр числа отдельно работала.
P.S. В прошлый раз не так условие поняла
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
30.04.2017, 21:24
Ответы с готовыми решениями:

Найти все трехзначные числа,равные кубу суммы своих своих цифр.
1. Найти все трехзначные числа,равные кубу суммы своих своих цифр. 2.Напечатать в возрастающем...

Найти все трехзначные числа, каждое из которых в 19 раз больше суммы своих цифр
Помогите составить программу : найти все трехзначные числа, каждое из которых в 19 раз больше суммы...

Найти все натуральные трехзначные числа, каждое из которых в 19 раз больше суммы своих цифр.
Найти все натуральные трехзначные числа, каждое из которых в 19 раз больше суммы своих цифр. ...

Найти все трёхзначные числа, равные сумме кубов своих цифр
Найти все трёхзначные числа, равные сумме кубов своих цифр.

15
Модератор
Эксперт по электронике
8476 / 4335 / 1642
Регистрация: 01.02.2015
Сообщений: 13,461
Записей в блоге: 8
30.04.2017, 22:48 2
Вы в асм вставке переменной цикла выбрали ecx, а проверку делаете для переменной b (строки 19, 26).
Ну и как-то сложно вы выполняете проверку.

Сделал без проверки - т.к. нет VS.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
_asm
{
    mov ecx, b
START:
    cmp ecx, border
    jge END
 
    push ebx
    mov eax, ecx  //проверяемое число
    mov ebx, 0    //сумма цифр числа
POINT1:
    cdq
    div ten
    add ebx, edx
    cmp eax, 0
    jne POINT1
 
    mov eax, ebx
    pop ebx
    mul eax        //возводим сумму цифр в квадрат
 
    mov tmp, ecx
    cmp ecx, eax
    jle NEXT
}
    cout << tmp << endl;
_asm
{
NEXT:
    inc ecx
    jmp START
END:
}
Это, если разрешено делать переходы на метки в другом асм блоке.
0
0 / 0 / 0
Регистрация: 23.11.2016
Сообщений: 30
01.05.2017, 00:35  [ТС] 3
ФедосеевПавел,Мне выдаёт число 100, а дальше прога вылетает. Продебажила выдаёт ошибку на 13 строке (integer overflow). Понятно, что что-то с регистрами при делении, но как это исправить?
0
1718 / 567 / 187
Регистрация: 12.03.2016
Сообщений: 2,169
01.05.2017, 06:15 4
Ничего, что после 26 строки регистр ecx изменяется? А раз
Цитата Сообщение от Александра_99 Посмотреть сообщение
прога вылетает
значит он > 1000
0
Ушел с форума
Автор FAQ
16279 / 7604 / 1065
Регистрация: 11.11.2010
Сообщений: 13,617
01.05.2017, 07:36 5
мановар,
вылетает потому, что edx заполняется командой cdq, а пара edx:eax делится командой div (противоречия никто не заметил? ) а вообще переполнение (divide by zero) будет всегда, когда делитель меньше или равен AH/DX/EDX/RDX
По условию задачи, для начала, нужно отсеять числа больше чем 243=3*92 (максимальная сумма квадратов цифр), а уже потом сравнивать оставшиеся числа с сумой квадратов
0
1718 / 567 / 187
Регистрация: 12.03.2016
Сообщений: 2,169
01.05.2017, 07:50 6
Лучший ответ Сообщение было отмечено ФедосеевПавел как решение

Решение

Mikl___, проверял через отладчик. Если сохраняешь ecx, а потом восстанавливаешь, то все начинает работать (до определенного момента, дальше не разбирался, хотя догадываюсь почему).
<offtop>
быстро пробежался отладчиком, увидел косяк с ecx и <offtop> не стал вникать не то что в детали, даже в саму программу.
0
0 / 0 / 0
Регистрация: 23.11.2016
Сообщений: 30
01.05.2017, 10:22  [ТС] 7
мановар, Да нет же! Признаю, что косяк был, но что мне делать, если я хочу разобраться с задачей, но НЕ МОГУ это сделать самостоятельно? Пожалуйста, подскажите, где eaх восстанавливать?
0
Модератор
Эксперт по электронике
8476 / 4335 / 1642
Регистрация: 01.02.2015
Сообщений: 13,461
Записей в блоге: 8
01.05.2017, 10:50 8
замените в моём коде строку 12 на mov edx,0

Mikl___, мановар, обратите внимание, что эта задача отличается от другой темы топикстартера. Здесь нужно возвести в квадрат сумму цифр, а не получить сумму квадратов цифр.

Добавлено через 9 минут
Ерунда какая-то.
Хотел обойтись одними регистрами, но, видимо, придётся добавлять переменные.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
int i;
_asm
{
    mov ecx, b
    mov i, ecx
START:
    mov ecx, i
    cmp ecx, border
    jge END
 
    push ebx
    mov eax, ecx  //проверяемое число
    mov ebx, 0    //сумма цифр числа
POINT1:
    mov edx, 0
    div ten
    add ebx, edx
    cmp eax, 0
    jne POINT1
 
    mov eax, ebx
    pop ebx
    mul eax        //возводим сумму цифр в квадрат
 
    mov tmp, ecx
    cmp ecx, eax
    jle NEXT
}
    cout << tmp << endl;
_asm
{
NEXT:
    inc i
    jmp START
END:
}
1
1718 / 567 / 187
Регистрация: 12.03.2016
Сообщений: 2,169
01.05.2017, 11:16 9
Цитата Сообщение от ФедосеевПавел Посмотреть сообщение
отличается от другой темы
Да заметели как то.
Цитата Сообщение от ФедосеевПавел Посмотреть сообщение
добавлять переменные
Не надо. У нас есть b = 100, ее и инкриминировать поэтому строки 1,4, 5 лишние
стр.7 mov ecx, b
стр.33 inc b
Только подозреваю это еще не все.

Добавлено через 6 минут
К стати, если строку 15 mov edx, 0 заменить на cdq, все прекрасно работает.
1
Модератор
Эксперт по электронике
8476 / 4335 / 1642
Регистрация: 01.02.2015
Сообщений: 13,461
Записей в блоге: 8
01.05.2017, 12:16 10
На masm32
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
; #########################################################################
 
      .386
      .model flat, stdcall
      option casemap :none   ; case sensitive
 
; #########################################################################
 
    ; ------------------------------
    ; Build this app in console mode.
    ; ------------------------------
 
      include d:\masm32\include\windows.inc
 
      include d:\masm32\include\user32.inc
      include d:\masm32\include\kernel32.inc
      include d:\masm32\include\masm32.inc
 
      includelib d:\masm32\lib\user32.lib
      includelib d:\masm32\lib\kernel32.lib
      includelib d:\masm32\lib\masm32.lib
; #########################################################################
 
    .data
      hConsoleOutput    HANDLE  ?
      hConsoleInput     HANDLE  ?
 
      Len               dword   0           ;длина считанной строки
      Buffer            db      128 dup(?)  ;буфер чтения
 
 
      Ten       dd  10
 
    temp        dd  0
 
      aszPrompt         db      "Count number > ", 0Dh, 0Ah, 0
      aszResult         db      "%d " ,0
      aszPressEnter     db      0Dh, 0Ah, "Press ENTER to exit", 0
; #########################################################################
 
    .code
  Main   PROTO
 
    start:
      invoke Main
      invoke ExitProcess,0
 
; #########################################################################
 
Main proc
  ; -------------------------------
  ; console mode library procedures
  ; -------------------------------
 
    invoke  GetStdHandle, STD_INPUT_HANDLE
    mov     hConsoleInput, eax
 
    invoke  GetStdHandle, STD_OUTPUT_HANDLE
    mov     hConsoleOutput, eax
 
    invoke ClearScreen
 
    invoke WriteConsole, hConsoleOutput, ADDR aszPrompt, LENGTHOF aszPrompt - 1, ADDR Len, NULL
 
    mov ecx,    100
 
@@For:
    cmp ecx,    1000
    jae @@Break
    mov eax,    ecx ;число для анализа
    mov ebx,    0   ;сумма цифр
    @@Repeat:
        mov edx,    0
        div Ten
        add ebx,    edx
        cmp eax,    0
        jne @@Repeat
    mov eax,    ebx
    mul eax
    cmp ecx,    eax
    jbe @@Next
 
    pushad
    ;вывод на экран
    invoke wsprintf, ADDR Buffer, ADDR aszResult, ecx
    mov Len, eax
    invoke WriteConsole, hConsoleOutput, ADDR Buffer, Len, ADDR temp, NULL
    popad
 
@@Next:
    inc ecx
    jmp @@For
 
@@Break:
 
    ;ожидание нажатия ENTER
    invoke WriteConsole, hConsoleOutput, ADDR aszPressEnter, LENGTHOF aszPressEnter - 1, ADDR Len, NULL
    invoke ReadConsole, hConsoleInput, ADDR Buffer, LENGTHOF Buffer, ADDR Len, NULL
 
    ret
 
Main endp
 
; #########################################################################
 
   end start
Я подозреваю, что под условие "трёхзначные числа, большие квадрата суммы своих цифр" подходят все трёхзначные числа. Ну да ладно.
Проблема в том, что вызов WinAPI разрушает содержимое регистров.
Нужно перед вызовом функции печати сохранить все регистры pushad/popad.

Добавлено через 5 минут
Нет, не все числа - сорок чисел не подходят (119, 129, 138, ..., 399).
И, наверное, так на C++
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
int i;
_asm
{
    mov ecx, b
    mov i, ecx
START:
    mov ecx, i
    cmp ecx, border
    jge END
 
    push ebx
    mov eax, ecx  //проверяемое число
    mov ebx, 0    //сумма цифр числа
POINT1:
    mov edx, 0
    div ten
    add ebx, edx
    cmp eax, 0
    jne POINT1
 
    mov eax, ebx
    pop ebx
    mul eax        //возводим сумму цифр в квадрат
 
    mov tmp, ecx
    cmp ecx, eax
    jle NEXT
    pushad
}
    cout << tmp << endl;
_asm
{
    popad
NEXT:
    inc i
    jmp START
END:
}
Добавлено через 3 минуты
мановар, да, т.к. числа трёхзначные, можно применять cdq, как я вначале и пытался.
По поводу использования b вместо i - я бы предпочёл использовать i, т.к. b и border могут быть объявлены константами. Но это вкусовщина.

Добавлено через 3 минуты
Хотел поставить +1 в сообщение о порче регистров - т.к. оно ключевое для решения, но там обидные для ТС размышления. Может сложится превратное суждение о том, что заслужило оценку.

Удалю лишнее и поставлю.
0
1718 / 567 / 187
Регистрация: 12.03.2016
Сообщений: 2,169
01.05.2017, 12:16 11
Цитата Сообщение от ФедосеевПавел Посмотреть сообщение
Я подозреваю, что под условие "трёхзначные числа, большие квадрата суммы своих цифр" подходят все трёхзначные числа.
Число 119 ---> (1 + 1 + 9)^2 = 11^2=121 (к примеру)
Только я думаю, что вот эти числа и надо было выводить, которые не больше. Их как раз и не много.
1
Модератор
Эксперт по электронике
8476 / 4335 / 1642
Регистрация: 01.02.2015
Сообщений: 13,461
Записей в блоге: 8
01.05.2017, 12:26 12
Да, изменив условие для вывода (masm32 строка 81) на ja @@Next получаю на выходе 40 чисел.
Но с этим пусть уже ТС разбирается. Постановка задачи идёт от него.
Миниатюры
Найти все трёхзначные числа, большие квадрата суммы своих цифр. Исправить код  
0
0 / 0 / 0
Регистрация: 23.11.2016
Сообщений: 30
01.05.2017, 13:49  [ТС] 13
ФедосеевПавел, мановар, нет, условие теперь точно правильное) Согласна, лучше было б выводить те 40 чисел, но не я придумываю задачи, а препод. Спасибо, за код, за время, за объяснения. Надеюсь, больше косяков не будет.
0
Модератор
Эксперт по электронике
8476 / 4335 / 1642
Регистрация: 01.02.2015
Сообщений: 13,461
Записей в блоге: 8
01.05.2017, 15:03 14
Теперь работает? Т.к. у меня нет VS - даже проверить не могу (проверял только в masm32).
0
1718 / 567 / 187
Регистрация: 12.03.2016
Сообщений: 2,169
01.05.2017, 15:36 15
ФедосеевПавел, по моему и в 8 пост. работал.
0
Модератор
Эксперт по электронике
8476 / 4335 / 1642
Регистрация: 01.02.2015
Сообщений: 13,461
Записей в блоге: 8
01.05.2017, 16:36 16
Тот #8 мог и не работать, т.к. содержимое регистров разрушалось при выводе на печать. А позже я обрамил вывод сохранением и восстановлением регистров.
0
01.05.2017, 16:36
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
01.05.2017, 16:36
Помогаю со студенческими работами здесь

Найти все трёхзначные числа, равные сумме факториала своих цифр
помогите пожалуйста решить задачу...Найти все трёхзначные числа, равные сумме факториала своих цифр

Найти все трехзначные числа, равные сумме квадратов своих цифр
Найти все трехзначные числа равные сумме квадратов своих цифр. с помощью цикла for

Найти все трехзначные числа, делящиеся на сумму своих цифр. PHP
Найти все трехзначные числа, делящиеся на сумму своих цифр. Добавлено через 5 минут Помогите...

Найти все трехзначные числа, равные сумме кубов своих цифр
Найти все трехзначные числа, равные сумме кубов своих цифр. Учтите, что аbc=100а+10b+с


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru