Показать сообщение отдельно
Старый 31.03.2011, 20:45   #1
Ksanatos
ПроЭктировщик
 
Аватар для Ksanatos
 
Регистрация: 31.01.2010
Адрес: Россия, респ. Башкортостан, г. Бирск
Сообщений: 137
Написано 12 полезных сообщений
(для 17 пользователей)
Сложение вещественных чисел произвольной длины.

В общем мне оказалось нужно сделать это. Вещественные числа такого типа: [-]целое[.дробь]
Решил засунуть всё это в строку и для сложение только что написал следующую функцию. Но она слишком монструозная. Помойму я намудрил много. В общем вот:
function Addition(FirstSummandSecondSummand stringAdditionType char;): string;
  var
    
FSChar,SSChar char//положение чисел на корд. прямой относительно нуля.
    
bufer string;
    
minus boolean//менять ли знак после действия.
    
FSl,SSl,len,frlen integer//длина 1 и 2 числа, длина целой части большего, и длина большей дробной части.
    
q,w,integer;
    
ch1,ch2 char;
    
int,int1,int2 integer;
    
resultat string;
    
integer;
  
begin
    
//определение положения чисел на корд. прямой относительно нуля.
    
FSChar:=getChar(FirstSummand,0);
    
SSChar:=getChar(SecondSummand,0);
    if 
FSChar<>'-' then
      FSChar
:='+';
    if 
SSChar<>'-' then
      SSChar
:='+';
    
//--------------------------------------------------------------------------------
    //упрощение выражений. Например "a--b"="a+b"
    
if (FSChar='-') and (Additiontype='-') and (SSChar='-'then
      begin
        SSChar
:='+';
        
AdditionType:='+';
      
end;
    if (
FSChar='-') and (AdditionType='+') and (SSChar='+'then
      begin
        bufer
:=FirstSummand;
        
FirstSummand:=SecondSummand;
        
SecondSummand:=bufer;
        
FSChar:='+';
        
SSChar:='+';
        
AdditionType:='-';
      
end;
    if 
SSChar='-' then
      
if AdditionType='-' then
        AdditionType
:='+';
      else
        
AdditionType:='-';
    if (
FSChar='-') and (AdditionType='-'then
      begin
        minus
:=true;
        
FSChar:='+';
        
AdditionType:='+';
      
end;
    if (
FirstSummand<SecondSummand) and (AdditionType='-'then // если уменьшаемое меньше вычитаемого, удобнее будет их поменять местами.
      
begin
        bufer
:=FirstSummand;
        
FirstSummand:=SecondSummand;
        
SecondSummand:=bufer;
        if 
minus then
          minus
:=false;
        else
          
minus:=true;
      
end;
    
//-------------------------------------------------------
    //определение наибольших длин целой и дробной части
    
u:=0;
    
q:=length(FirstSummand);
    
w:=length(SecondSummand);
    if 
pos(FirstSummand,'.')<>-1 then
      q
:=pos(FirstSummand,'.');
    if 
pos(SecondSummand,'.')<>-1 then
      w
:=pos(SecondSummand,'.');
    
FSl:=length(copy(FirstSummand,0,q));
    
SSl:=length(copy(SecondSummand,0,w));
    if 
FSl>=SSl then
      len
:=FSl;
    else
      
len:=SSl;
    if (
length(FirstSummand)-q)>=(length(SecondSummand)-wthen
      frlen
:=length(FirstSummand)-q;
    else
      
frlen:=length(SecondSummand)-w;
    
//----------------------------------------------------------------------------
    //добавление нулей, для упрощения действия, а также для выравнивания положения запятой.
    
FirstSummand:=StringWithZero(FirstSummand,len,frlen);
    
SecondSummand:=StringWithZero(SecondSummand,len,frlen);
    
//----------------------------------------------------------------------------
    //само действие
    
for i:=length(FirstSummand)-1 downto 0 do
      
begin
        ch1
:=getChar(FirstSummand,i); //считывание посимвольно с конца.
        
ch2:=getChar(SecondSummand,i);
        if 
ch1<>'.' then
          begin
            int1
:=StringToInteger(''+ch1);
            
int2:=StringToInteger(''+ch2);
            if 
AdditionType='+' then // сложение
              
begin
                int
:=int1+int2;
                if 
int<10 then
                  begin
                    int
:=int+u//если в предыдущий раз сумма была больше 10 к int надо прибавить u
                    
resultat:=''+int+resultat;
                    
u:=0//u использовали, опять делаем её нулевой
                  
end;
                else 
// если сумма цифр больше 10, то к следующему разряду нужно прибавить 1, это записываеться в u (на другое имя фагтазии не хватило :) )
                  
begin
                    int
:=int-10+u//вычитаем 10 и прибавляем последствия прошедших действий
                    
resultat:=''+int+resultat;
                    
u:=1//ну и, конечно, инициируем u для следующего раза.
                  
end;
              
end;
            else if 
AdditionType='-' then // вычитание
              
begin
                
if (int1-u)<int2 then // если первая цифра(с заранее учтёнными прошлыми действиями) меньше второй, то из следующей цифры уменьшаемого вычесть 1
                  
begin
                    int
:=int1-u+10-int2// из i-ной цифры уменьшаемого вычитаем i-ную цифру вычитаемого прибавляем 10, чтоб значение не было отрицательным и вычитаем u 
                    
u:=1// u естественно приравниваем 1 для следующего действия
                  
end;
                else 
// ничего нового, что надо было бы объяснять
                  
begin
                    int
:=int1-u-int2;
                    
u:=0;
                  
end;
                
resultat:=''+int+resultat;
              
end;
          
end;
        else
          
resultat:='.'+resultat// дошли до точки, ставим точку и в результате
       
end;
    if (
u<>0) and (AdditionType='+'then // оставшиеся действия
      
resultat:='1'+resultat;
    if (
u<>0) and (AdditionType='-'then
      
if minus then
        minus
:=false;
      else
        
minus:=true;
    if 
minus then
      Addition
:='-'+resultat;
    else
      
Addition:=resultat;
  
//----------------------------------------
  
end
Функция для добавлению нулей в начало и конец строки:
function StringWithZero(bufstring stringint,frc integer): string;
  var
    
integer;
    
bufstring2 string;
  
begin
    i
:=1;
    if 
frc<>0 then
      begin
        
if pos(bufstring,'.')=-1 then
          bufstring
:=bufstring+'.';
        
bufstring2:=copy(bufstring,pos(bufstring,'.')+1,length(bufstring));
        
i:=0;
        while 
i<(frc-length(bufstring2)) do
          
begin
            bufstring
:=bufstring+'0';
            
i:=i+1;
          
end;
        
bufstring2:=copy(bufstring,0,pos(bufstring,'.'));
        
i:=0;
        while 
i<(int-length(bufstring2)) do
          
begin
            bufstring
:='0'+bufstring;
            
i:=i+1;
          
end;
      
end;
    else
      while 
i<(int-length(bufstring)+1) do
        
begin
          bufstring
:='0'+bufstring;
          
i:=i+1;
        
end;
    
StringWithZero:=bufstring;
  
end
__________________




Последний раз редактировалось Ksanatos, 02.04.2011 в 05:29. Причина: Устранил ошибки, теперь функции полностью рабочии.
(Offline)
 
Ответить с цитированием