Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 19.03.2018, 09:13
igor74 igor74 вне форума
Прохожий
 
Регистрация: 08.06.2011
Адрес: Екатеринбург
Сообщения: 11
Версия Delphi: Delphi 2010
Репутация: -625
По умолчанию Как отбросить дробную часть

Всем привет!

Пишу графику и мне в расчётах нужно отбрасывать дробную часть переводя в целое.

Так вот Trunc работает в два раза дольше чем Round. Время для меня очень критично, поэтому ищу варианты решения данной задачи.

Ассемблерные вставки не помогают или я делаю что то не так...

У кого есть какие идеи?

Вот код:
Код:
  dx := w1 / w2;
  dy := h1 / h2;

  for y := 0 to h2 - 1 do
  begin
   yp := Trunc(y * dy);
   ypw1 := yp * w1;
   yw2 := y * w2;
   for x := 0 to w2 - 1 do
    begin
      xp := Trunc(x * dx);
      col := ypw1 + xp;
      Mem2[yw2 + x] := Mem1[col];
    end;
  end;
Ответить с цитированием
  #2  
Старый 19.03.2018, 10:23
Аватар для dr. F.I.N.
dr. F.I.N. dr. F.I.N. вне форума
I Like it!
 
Регистрация: 12.12.2009
Адрес: Россия, г. Новосибирск
Сообщения: 660
Версия Delphi: D6/D7
Репутация: 26643
По умолчанию

Не быстрее Round, но быстрее Trunc.
Код:
function Trunc_Dbl(Value: Double): Integer;
var
  d_w: array[0..3] of word absolute Value;
begin
  Result := ((d_w[3] shl 11) or (d_w[2] shr 5) or $8000) shr (14 - (d_w[3] shr 4 and $03FF));
end;

function Trunc_Asm(Value: Double): Integer;
const
  Half: double = 0.5;
begin
  asm
        fld     Value
        fsub    Half
        fistp   Result
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  I: Integer;
  tc1, tc2, tc3, tc4: Cardinal;
  _value: Double;
  _result: Integer;
begin
  _value := 100.56;
  tc1 := GetTickCount;
  for I := 0 to $FFFFFF do
  begin
    _result := Trunc(_value);
    if _result = 99 then
      ;
  end;
  tc1 := GetTickCount - tc1;
  //-------------
  tc2 := GetTickCount;
  for I := 0 to $FFFFFF do
  begin
    _result := Trunc_Asm(_value);
    if _result = 99 then
      ;
  end;
  tc2 := GetTickCount - tc2;
  //-------------
  tc3 := GetTickCount;
  for I := 0 to $FFFFFF do
  begin
    _result := Trunc_Dbl(_value);
    if _result = 99 then
      ;
  end;
  tc3 := GetTickCount - tc3;
  //-------------
  tc4 := GetTickCount;
  for I := 0 to $FFFFFF do
  begin
    _result := Round(_value);
    if _result = 99 then
      ;
  end;
  tc4 := GetTickCount - tc4;
  //-------------
  ShowMessageFmt('Trunc: %d'#13'Trunc_Asm: %d'#13'Trunc_Dbl: %d'#13'Round: %d', [tc1, tc2, tc3, tc4]);
end;
__________________
Грамотно поставленный вопрос содержит не менее 50% ответа.
Грамотно поставленная речь вызывает уважение, а у некоторых даже зависть.

Последний раз редактировалось dr. F.I.N., 19.03.2018 в 19:20.
Ответить с цитированием
  #3  
Старый 20.03.2018, 11:24
Аватар для dr. F.I.N.
dr. F.I.N. dr. F.I.N. вне форума
I Like it!
 
Регистрация: 12.12.2009
Адрес: Россия, г. Новосибирск
Сообщения: 660
Версия Delphi: D6/D7
Репутация: 26643
Лампочка

Покопавшись, нашел еще вариант. Полагаю то, что Вам нужно.
Код:
function TruncMEM_SSE(Var Value: Double): Integer;
asm
  // as written, fatest version
  CVTTSD2SI  EAX, [Value]
end;


И вот еще наблюдение.
Код:
function Trunc_Dbl(var Value: Double): Integer;  // VAR
var
  d_w: array[0..3] of word absolute Value;
begin
  Result := ((d_w[3] shl 11) or (d_w[2] shr 5) or $8000) shr (14 - (d_w[3] shr 4 and $03FF));
end;
В таком варианте функция Trunc_Dbc работает чуть быстрее Round (219-234 тика на том же тесте), а функция TruncMEM_SSE без VAR работает медленнее (390 тиков при том же тесте).
__________________
Грамотно поставленный вопрос содержит не менее 50% ответа.
Грамотно поставленная речь вызывает уважение, а у некоторых даже зависть.

Последний раз редактировалось dr. F.I.N., 20.03.2018 в 11:30.
Ответить с цитированием
  #4  
Старый 21.03.2018, 14:49
igor74 igor74 вне форума
Прохожий
 
Регистрация: 08.06.2011
Адрес: Екатеринбург
Сообщения: 11
Версия Delphi: Delphi 2010
Репутация: -625
По умолчанию Тема закрыта

dr. F.I.N., спасибо, "TruncMEM_SSE" то что доктор прописал!

Ещё раз спасибо, тема закрыта
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

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

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 23:18.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter