Извините, ничего не найдено.

Не расстраивайся! Лучше выпей чайку!
Регистрация
Справка
Календарь

Вернуться   forum.boolean.name > Программирование игр для мобильных телефонов > MidletPascal > Основной форум

Основной форум Сюда все проблемы связанные с программированием.

Ответ
 
Опции темы
Старый 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)
 
Ответить с цитированием
Старый 01.04.2011, 22:24   #2
Igor
Мастер
 
Аватар для Igor
 
Регистрация: 03.05.2010
Адрес: Подмосковье
Сообщений: 1,218
Написано 438 полезных сообщений
(для 790 пользователей)
Ответ: Сложение вещественных чисел произвольной длины.

Код вроде как хороший, тока разобраться без комментов трудновато (между '//само действие' и '//---------')
UPD: вроде разобрался.
__________________
О¯О ¡¡¡ʁɔvʎнdǝʚǝdǝu dиW
(Offline)
 
Ответить с цитированием
Старый 02.04.2011, 03:00   #3
Ksanatos
ПроЭктировщик
 
Аватар для Ksanatos
 
Регистрация: 31.01.2010
Адрес: Россия, респ. Башкортостан, г. Бирск
Сообщений: 137
Написано 12 полезных сообщений
(для 17 пользователей)
Ответ: Сложение вещественных чисел произвольной длины.

Простите за отсутствие комментов. Вчера я был уже пуст и заново понять то что написал не получалось ))
Хотелось бы услышаь предложения по сжатию этого кода, если это вообще возможно...
__________________




Последний раз редактировалось Ksanatos, 02.04.2011 в 05:31.
(Offline)
 
Ответить с цитированием
Старый 02.04.2011, 22:47   #4
YellowAfterlife
ПроЭктировщик
 
Аватар для YellowAfterlife
 
Регистрация: 19.02.2011
Сообщений: 134
Написано 81 полезных сообщений
(для 219 пользователей)
Ответ: Сложение вещественных чисел произвольной длины.

Пожалуй, при использовании "чистого" МП максимальной скорости выполнения достигнуть не возможно, просто потому что код не транслируется нужным способом, и не работает на максимальной скорости.
Если вам функция до сих пор нужна, я написал аналогичную (точнее, несколько их) на "чистой" яве и сделал библиотеку -
http://forum.boolean.name/showthread...ewpost&t=14515
По ЛС могу сбросить исходный код - функции занимают 26, 34, и 42 строк для сложения, вычитания, и умножения соответственно.
__________________

Мой сайт-блог. Игры, обновления, примеры для Haxe, JavaScript(+HTML5), GameMaker, Love2d...
(Offline)
 
Ответить с цитированием
Старый 02.04.2011, 22:58   #5
den
Дэвелопер
 
Аватар для den
 
Регистрация: 13.02.2010
Сообщений: 1,645
Написано 620 полезных сообщений
(для 2,419 пользователей)
Ответ: Сложение вещественных чисел произвольной длины.

А в телефонной Java нет классов BigInteger и BigDecimal ??
(Offline)
 
Ответить с цитированием
Старый 02.04.2011, 23:47   #6
YellowAfterlife
ПроЭктировщик
 
Аватар для YellowAfterlife
 
Регистрация: 19.02.2011
Сообщений: 134
Написано 81 полезных сообщений
(для 219 пользователей)
Ответ: Сложение вещественных чисел произвольной длины.

Сообщение от Den Посмотреть сообщение
А в телефонной Java нет классов BigInteger и BigDecimal ??
В спецификацию не включен ни то что java.lang.Number, а даже java.math, из которого берутся все функции. То есть как факт, вы можете тестировать MIDlet с таким типом на компьютере (через эмулятор), но на устройстве он будет падать на запуске с "No class definition found".
__________________

Мой сайт-блог. Игры, обновления, примеры для Haxe, JavaScript(+HTML5), GameMaker, Love2d...
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
den (02.04.2011)
Старый 03.04.2011, 16:13   #7
Igor
Мастер
 
Аватар для Igor
 
Регистрация: 03.05.2010
Адрес: Подмосковье
Сообщений: 1,218
Написано 438 полезных сообщений
(для 790 пользователей)
Ответ: Сложение вещественных чисел произвольной длины.

Маленький совет по оптимизации. Можно в каждый символ писать не одну цифру, а две. (ord и chr в помощь)
Количество операций должно уменьшится почти в два раза.
__________________
О¯О ¡¡¡ʁɔvʎнdǝʚǝdǝu dиW
(Offline)
 
Ответить с цитированием
Старый 04.04.2011, 14:59   #8
abcdef
Знающий
 
Регистрация: 16.09.2008
Сообщений: 299
Написано 71 полезных сообщений
(для 123 пользователей)
Ответ: Сложение вещественных чисел произвольной длины.

вот пример, но только для сложения положительных чисел:
var
  idTxt : integer;
  cmdExit : command;
  a,b : string;


function sum(a,b : string) : string;
var
  s : string;
  ap,bp : integer;
  sm,ost : integer;
begin
  ap:=pos(a,'.');
  bp:=pos(b,'.');
  if (ap=-1) then begin a:=a+'.'; ap:=pos(a,'.'); end;
  if (bp=-1) then begin b:=b+'.'; bp:=pos(b,'.'); end;
  while (ap<bp) do begin a:='0'+a; ap:=ap+1; end;
  while (bp<ap) do begin b:='0'+b; bp:=bp+1; end;
  ap:=length(a);
  bp:=length(b);
  while (ap<bp) do begin a:=a+'0'; ap:=ap+1; end;
  while (bp<ap) do begin b:=b+'0'; bp:=bp+1; end;
  s:='';
  ost:=0;
  for ap:=bp-1 downto 0 do
  begin
    if getChar(a,ap)<>'.' then
    begin
      sm:=(ord(getChar(a,ap))-48) + (ord(getChar(b,ap))-48);
      if ost>0 then begin sm:=sm+ost; ost:=0; end;
      while sm>=10 do begin sm:=sm-10; ost:=ost+1; end;
      s:=''+sm+s;
    end
    else s:='.'+s;
  end;
  if ost>0 then s:=''+ost+s;
  sum:=s;
end;


begin
  showForm;
  a:='12999999';
  b:='6789.2999';
  idTxt := formAddString(a+'+'+b+'='+sum(a,b));
  cmdExit := createCommand('Exit', CM_EXIT, 1);
  addCommand(cmdExit);
  repeat delay(1000); until getClickedCommand=cmdExit;
end.
(Offline)
 
Ответить с цитированием
Старый 04.04.2011, 22:29   #9
Ksanatos
ПроЭктировщик
 
Аватар для Ksanatos
 
Регистрация: 31.01.2010
Адрес: Россия, респ. Башкортостан, г. Бирск
Сообщений: 137
Написано 12 полезных сообщений
(для 17 пользователей)
Ответ: Сложение вещественных чисел произвольной длины.

Спасибо всем.
2YellowAfterlife
Я уже написал две функции(сложение и вычитание вместе и умножение) универсальные, для всех типов чисел сразу, на МП. Внедрять в проект твою либу, пока слишком муторно выйдет. Но всё равно спасибо. Сейчас ломаю голову над делением...
По ЛС могу сбросить исходный код
В яве не силён, пока только учусь, так что, врятли я что-нибудь пойму...
И вопрос тебе:
в одном объекте String может хранится до двух миллиардов символов
в МП также или только 255 символов?
2Igor
Не катит, я повсеместно использую pos...
2abcdef
Спасибо, у себя много недочётов нашел.
while sm>=10 do begin sm:=sm-10; ost:=ost+1; end;
строчка лишняя, больше 18 нельзя получить при сумме двух цифр и ещё единица с предыдущего сложения.
__________________



(Offline)
 
Ответить с цитированием
Старый 05.04.2011, 02:46   #10
YellowAfterlife
ПроЭктировщик
 
Аватар для YellowAfterlife
 
Регистрация: 19.02.2011
Сообщений: 134
Написано 81 полезных сообщений
(для 219 пользователей)
Ответ: Сложение вещественных чисел произвольной длины.

Сообщение от Ksanatos Посмотреть сообщение
Спасибо всем.
2YellowAfterlife
Я уже написал две функции(сложение и вычитание вместе и умножение) универсальные, для всех типов чисел сразу, на МП. Внедрять в проект твою либу, пока слишком муторно выйдет. Но всё равно спасибо. Сейчас ломаю голову над делением...

В яве не силён, пока только учусь, так что, врятли я что-нибудь пойму...
И вопрос тебе:

в МП также или только 255 символов?
МП так же поддерживает длинные строки, потому что, о чудо, Никса не реализовал их через int'ы, в отличие от всех остальных типов переменных (да, даже boolean хранится в МП-МИДлете как int). Максимальное число символов - 2147483647 (0x7FFFFFFF). Хотя, в прочем, не очень вероятно что это имеет значение, учитывая то что на телефонах нет столько памяти

Про библиотеку - я ее сделал, поскольку "обычные" методы java работают в разы быстрее даже самых правильных функций в МП (см. те же непонятные преобразования ((booleancondition ? 1 : 0) != 0) почти на каждом if'е, сделанным МП).

Функция realaddreal из библиотеки работает где-то так же как и ваша (принимает значения независимо от точки и знака, и делает все возможное для избежания ошибок). Остальные функции добавлены, поскольку при известном типе числа они обеспечивают даже большую производительность программы.
__________________

Мой сайт-блог. Игры, обновления, примеры для Haxe, JavaScript(+HTML5), GameMaker, Love2d...
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
Ksanatos (08.04.2011)
Старый 24.06.2011, 02:54   #11
Ksanatos
ПроЭктировщик
 
Аватар для Ksanatos
 
Регистрация: 31.01.2010
Адрес: Россия, респ. Башкортостан, г. Бирск
Сообщений: 137
Написано 12 полезных сообщений
(для 17 пользователей)
Ответ: Сложение вещественных чисел произвольной длины.

Проект куда я всё это запихнул ^_^.
__________________



(Offline)
 
Ответить с цитированием
Ответ


Опции темы

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Часовой пояс GMT +4, время: 14:03.


vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot
Style crйe par Allan - vBulletin-Ressources.com