06.04.2016, 13:27
общий
это ответ
Здравствуйте, EccoVIP!
Вот Вам программа:
[code h=200]
#include <malloc.h>
#include <string.h>
#include <stdio.h>
//преобразование в дополнительный код и обратно
//параметры:
// num - адрес числа
// len - его длина
// sign - 1/0 - надо/не надо преобразовывать
//num_dop = 999...999 - num + 1;
void MakeAddCode(char *num, int len, int sign)
{
int i, iCarry;
if (sign) //преобразовываем только если не 0
{
//отнимем от 9 все разряды, начиная с младшего
for (i=len-1; i>=0; i--)
num[i] = 9 - num[i];
//добавим 1
//сначала к младшему разряду
i = len-1; //его индекс
//проверим на перенос
if ((num[i] = num[i] + 1) > 9)
{
num[i] = 0; //отнимаем 10
iCarry = 1; //взводим перенос
}
else
iCarry = 0; //переноса нет
//все остальные разряды складываем с переносом
for (i--; i>=0; i--)
{
//проверяем на перенос
if ((num[i] += iCarry) > 9)
{
num[i] -= 10;
iCarry = 1;
}
else
iCarry = 0;
}
}
}
//преобразование строки символов в число
//параметры:
//op - строка символов
//len = ее длина
//num - адрес указателя на число
//lenr = длина числа
int GetNum(char* op, int len, char** num, int lenr)
{
int sign = 0; //знак числа
int iop; //индекс по строке символов
int inum; //индекс по числу
//выделим память под число
if (0 == (*num = (char*)malloc(lenr)))
return -2; //ошибка памяти!
//идем по строке символов с конца
for(inum=lenr-1,iop=len-1; iop>=0 ;iop--,inum--)
{
switch(op[iop]) //проверяем на цифры, +, -
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': //символы-цифры превлащаем в цифры
(*num)[inum] = op[iop] & 0x0f;
break;
case '-':
if (iop != 0)
return -1; //минус можно писать только в первой позиции
(*num)[inum] = 0; //в число напишем разряд = 0
sign = 1; //пометим, что число отрицательное
break;
case '+':
if (iop != 0)
return -1; //плюс также можно писать только в первой позиции
(*num)[inum] = 0; //в число напишем разряд = 0
break;
default:
return -1; //все остальное - ошибка формата!
}
}
for (; inum>=0; inum--) //все остальные разряды до начала числа = 0
(*num)[inum] = 0;
MakeAddCode(*num, lenr, sign); //если надо, превратим в доп код
return 0; //число корректное
}
//складываем opf = opf + ops
//результат - в *res
//после использования результата необходимо освободить память *res
int sum(char* opf, char*ops, char**res)
{
int lenf = strlen(opf); //длина строки opf
int lens = strlen(ops); //длина строки ops
//найдем длину строки результата,
// такой же длины будут и длины чисел операндов
// lenr = max(lenf,lens) + 2
int lenr = 2 + ((lenf>lens)?lenf:lens);
int iRes, i, iCarry;
char * regf; //адрес числа 1
char * regs; //адрес числа 2
//преобразовываем строку 1 opf в число 1
iRes = GetNum(opf, lenf, ®f, lenr);
if (iRes < 0)
return iRes; //если ошибка
//преобразовываем строку 2 ops в число 2
iRes = GetNum(ops, lens, ®s, lenr);
if (iRes < 0)
return iRes; //если ошибка
*res = (char*)malloc(lenr); //выделим память под результат
if (res == 0)
return -2; //если ошибка
//складываем числа, начинаем с младшего разряда
// учитываем перенос
for (iCarry=0,i=lenr-1; i>=0; i--)
{
if ((regf[i] = regf[i] + regs[i] + iCarry) > 9)
{
regf[i] -= 10;
iCarry = 1; //перенос
}
else
iCarry = 0;
}
//формируем строку результата из числа
iRes = 0; //индекс в строке результата
if (regf[0] == 9) //проверим, отрицательное ли число
{
MakeAddCode(regf, lenr, 1); //преобразовываем в прямой код
(*res)[iRes++] = '-'; //рисуем минус!
}
//преобразовываем все разряды (в прямом коде!) в строку цифр
// пропускаем незначащие нули
// iCarry = 0 означает, что нули незначащие - не выводим
// iCarry = 1 означает, что выводить надо все
// сначала пройдем все разряды, кроме последнего,
// который выводится в любом случае!
for (iCarry=0,i=0; i<lenr-1; i++)
{
if (iCarry)
(*res)[iRes++] = regf[i] + '0';
else if (regf[i])
{
iCarry = 1;
(*res)[iRes++] = regf[i] + '0';
}
}
//последний разряд выводим всегда
(*res)[iRes++] = regf[i] + '0';
//закрываем строку нулем
(*res)[iRes++] = 0;
//освобождаем память чисел
free(regf);
free(regs);
return 0; //все ок
}
int main()
{
char * res = 0; //указатель на строку-результат
//считаем и анализируем на ошибку
switch (sum("+2222", "-5550", &res))
{
case 0:
printf("Sum = %s\n", res);
free(res);
break;
case -1:
printf("Incorrect parameters!\n");
break;
case -2:
printf("Allocate memory error!\n");
}
return 0;
}
[/code]
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен