Проверка на переполнение при вычислении выражения - 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;
}

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

  1. Подключение необходимых библиотек для работы с числами и вводом-выводом
  2. Определение константы var, которая используется в формуле
  3. Объявление переменных a, b, c, a1, b1, c1, left, right, left_a, right_a иerr_la
  4. Ввод значений переменных a, b, c с помощью функции scanf
  5. Вычисление значений a1, b1, c1 с помощью деления a, b, c на var+2, var+3, var+4 соответственно
  6. Проверка на переполнение при вычислении a1^2, b1^2, a1^2+b1^2+c1^2, 2a1b1, 2a1c1, 2b1c1
  7. Вычисление значения выражения (a1^2+b1^2+c1^2-2ab-2ac+2bc)/2
  8. Вывод результатов вычисления на языке C++ и на языке ассемблера
  9. Проверка наличия ошибки (переполнения) и вывод соответствующего сообщения

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


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

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

11   голосов , оценка 4.273 из 5
Похожие ответы