Проверка на переполнение при вычислении выражения - C (СИ)
Формулировка задачи:
Доброго времени суток. Помогите пожалуйста с одним вопросом. Имеется задание: Написать программу, проверяющую ряд тождеств, часть из которых является общеизвестными арифметическими тождествами. Для этого необходимо вычислить левую и правую часть арифметического выражения. В процессе вычислений необходимо контролировать переполнение разрядной сетки. Результаты вычислений отображаются на экране.
Решить задачу необходимо на С++ и ассемблере.
Саму программу я написал, но вот как выполнить проверку на переполнение не знаю.. Вот сама программа
#include <stdio.h> #define var 14 int main() { int a,b,c,a1,b1,c1,left,right,left_a,right_a; printf("Input a, b, c for (a-b-c)^2 = a^2+b^2+c^2-2ab-2ac+2bc\n"); scanf("%i%i%i",&a,&b,&c); a1=a/(var+2); b1=b/(var+3); c1=c/(var+4); left = (a1-b1-c1)*(a1-b1-c1); right = (a1*a1)+(b1*b1)+(c1*c1)-2*a1*b1-2*a1*c1+2*b1*c1; __asm{ mov eax,a //a1=a/(var+2) cdq mov ebx,var+2 idiv ebx mov esi,eax mov eax,b //b1=b/(var+3) cdq mov ebx,var+3 idiv ebx mov edi,eax mov eax,c //c1=c/(var+4) cdq mov ebx,var+4 idiv ebx mov edx,eax // left= (a1-b1-c1)^2 mov eax,esi sub eax,edi sub eax,edx imul eax,eax mov left_a,eax // (a1*a1)+(b1*b1)+(c1*c1)-2*a1*b1-2*a1*c1+2*b1*c1 mov eax,esi // a1^2 imul eax,eax mov ebx,edi // b1^2 imul ebx,ebx mov ecx,edx // c1^2 imul ecx,ecx add eax,ebx // a1^2+b1^2+c1^2 add eax,ecx mov ebx,esi // 2*a1*b1 mov ecx,edi imul ebx,2 imul ebx,ecx sub eax,ebx mov ebx,esi //2*a1*c1 mov ecx,edx imul ebx,2 imul ebx,ecx sub eax,ebx mov ebx,edi //2*b1*c1 mov ecx,edx imul ebx,ecx imul ebx,2 add eax,ebx mov right_a,eax } // Вывод результатов printf("Result (C++) Right and Left: %i = %i\n",left,right); printf("Result (ASM) Right and Left: %i = %i\n",left_a,right_a); return 0; }
Решение задачи: «Проверка на переполнение при вычислении выражения»
textual
Листинг программы
#include <stdio.h> #include <iostream> using namespace std; #define var 14 int err, err_la,y; int main() { setlocale (LC_CTYPE, "rus"); int a,b,c,a1,b1,c1,left,right,left_a,right_a; err=0; printf("Введите переменные a, b, c для выражения (a-b-c)^2 = a^2+b^2+c^2-2ab-2ac+2bc\n"); scanf("%i%i%i",&a,&b,&c); a1=a/(var+2); b1=b/(var+3); c1=c/(var+4); err = 0; left = y; right = ((a1*a1)/(b1))-((b1*b1)/a); __asm{ mov err_la,0 mov eax,a //a1=a/(var+2) cdq mov ebx,var+2 idiv ebx mov a1,eax mov eax,b //b1=b/(var+3) cdq mov ebx,var+3 idiv ebx mov b1,eax mov eax,c //c1=c/(var+4) cdq mov ebx,var+4 idiv ebx mov c1,eax // mov eax,a1 // a1^2 imul eax,eax jo ERROR mov ebx,b1 // b1^2 imul ebx,ebx jo ERROR add eax,ebx // a1^2+b1^2+c1^2 add eax,ecx jo ERROR mov ebx,a1 // 2*a1*b1 mov ecx,b1 imul ebx,2 imul ebx,ecx jo ERROR sub eax,ebx mov ebx,a1 //2*a1*c1 mov ecx,c1 imul ebx,2 imul ebx,ecx sub eax,ebx jo ERROR mov ebx,b1 //2*b1*c1 mov ecx,c1 imul ebx,ecx imul ebx,2 jo ERROR add eax,ebx mov right_a,eax jmp END ERROR: mov err,1 END: } // Вывод результатов printf("Результаты вычисления на (C++): %i = %i\n",left,right); if (err==1) printf("\nОшибка! Переполнение!\n"); else printf("Результаты вычисления на (ASM): %i = %i\n",left_a,right_a); return 0; }
Объяснение кода листинга программы
- Подключение необходимых библиотек для работы с числами и вводом-выводом
- Определение константы var, которая используется в формуле
- Объявление переменных a, b, c, a1, b1, c1, left, right, left_a, right_a иerr_la
- Ввод значений переменных a, b, c с помощью функции scanf
- Вычисление значений a1, b1, c1 с помощью деления a, b, c на var+2, var+3, var+4 соответственно
- Проверка на переполнение при вычислении a1^2, b1^2, a1^2+b1^2+c1^2, 2a1b1, 2a1c1, 2b1c1
- Вычисление значения выражения (a1^2+b1^2+c1^2-2ab-2ac+2bc)/2
- Вывод результатов вычисления на языке C++ и на языке ассемблера
- Проверка наличия ошибки (переполнения) и вывод соответствующего сообщения
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д