Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Преобразование чисел


bestolkov ©   (2011-07-20 18:15:00) 

Всем здравствуйте! Существует ли остроумный способ преобразования числа из формата с плавающей точкой в фиксированную точку без потери точности?


MBo   (2011-07-21 14:39:00) [1]

Вот как схематично выглядит расположение на положительной числовой оси чисел с фиксированной и с плавающей запятой:
http://mbo88.narod.ru/Image2.gif

Преобразование без потерь возможно на участках, где фикс. идут чаще.
Например, если числа с фикс. точкой с восемью двоичными цифрами после запятой, то однозначное преобразование возможно для Double > 2^44.
Если нужно для любых - безумный путь в [3]


bestolkov   (2011-07-21 14:11:00) [2]

Ну, ключевое слово в вопросе - без потерь..


Барт   (2011-07-21 13:31:00) [3]

> Это ясно, а чем код лучше приведенного?

Остроумнее


RWolf   (2011-07-21 13:10:00) [4]


> Существует ли остроумный способ преобразования числа из
> формата с плавающей точкой в фиксированную точку без потери
> точности?


есть такой способ.

inline int float2int( double d ) {
   union Cast { double d; long l; };
   volatile Cast c;
   cd = d + 6755399441055744.0;
   return cl;
}


bestolkov   (2011-07-21 12:23:00) [5]


> MBo ©   (21.07.11 11:43) [9]

Это ясно, а чем код лучше приведенного?


MBo   (2011-07-21 11:43:00) [6]

Из числа с плавающей точкой выделяется мантисса и экспонента, и формируется число с фиксированной точкой в формате знак - 15 бит целой части - 16 бит дробной siiiiiii.ffffff


bestolkov   (2011-07-21 10:34:00) [7]

MBo ©   (21.07.11 10:06) [7]
Не совсем понял Вас, прокомментируйте ответ,пожалуйста


MBo   (2011-07-21 10:06:00) [8]

Неуий маразм для чисел, по модулю меньших 32767, без учета денормализованных и т.п.
Для крупных чисел больше значащих цифр сохраняется

var
 d, d2: Double;
 i64, m64, ex: Int64;
 ifixed_s_15_16: Integer;
begin
 Randomize;
 d := (Random - 0.5) * exp(Random * 10);
 Memo1.Lines.Add(FloatToStr(d));
 i64 := PInt64(@d)^;
 m64 := i64 and $000FFFFFFFC00000;
 m64 := m64 or $0010000000000000;
 ex := i64 shr 52;
 ex := ex and 2047;
 ex := ex - 1023;
 if ex < 0 then
   m64 := m64 shr (-ex)
 else
   m64 := m64 shl ex;
 m64:= m64 shr 36;
 ifixed_s_15_16 := m64;
 if i64 < 0 then
   ifixed_s_15_16 := - ifixed_s_15_16;
 d2 := ifixed_s_15_16 / 65536;
 Memo1.Lines.Add(FloatToStr(d2));


bestolkov   (2011-07-21 07:55:00) [9]


> MBo ©   (20.07.11 20:31) [1]

function f2lx(Real_value: Double ; const scale: real; bits: integer): lfix;
var value : Double ;
begin
   value:= Real_value / scale * LX_Range;
   if (value < 0) then
    begin
       value := value-0.5;
        if (value < -LX_Range) then Result:= $80000000  else  Result :=Round(value) and LMask[bits];
    end
   else
    begin
       value :=value+ 0.5;
       if (value > LX_MAX) then Result:=$7FFFFFFF  else Result:= Round(value) and LMask[bits];
    end;
end;


MBo   (2011-07-21 07:03:00) [10]

>хватит и меньше,
Это уже будет некое перекодирование


Полвторого   (2011-07-21 02:40:00) [11]


> MBo ©   (20.07.11 21:30) [3]

хватит и меньше, если учесть что на большом удалении от нуля между отдельными числами с плавающей точкой возникают дырки кое-где и больше единицы.


MBo   (2011-07-20 21:30:00) [12]

>Без потери точности по определению нельзя
Ну как же, всего (1 + 64 + 32768)=32833-битовое число понадобится для Extended ;)


Anatoly Podgoretsky   (2011-07-20 21:16:00) [13]

Без потери точности по определению нельзя


MBo   (2011-07-20 20:31:00) [14]

Приведите пример неостроумного преобразования, чтобы убедиться, что мы думаем об одних и тех же сущностях


Наверх

Титульная страница Поиск, карта сайта Написать письмо