реклама на сайте
подробности

 
 
> Float To Str, очень быстренькое преобразование
cf7k
сообщение Sep 25 2007, 12:27
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 82
Регистрация: 14-03-06
Из: Санкт-Петербург
Пользователь №: 15 227



А не сталкивался ли кто-либо с потребностью преобразования вещественно числа в строку?
Понятное дело - sprintf (&buf, "%F",....) в большинстве случаев эту проблему решает. Но есть несколько "но": эта ф-ция тянет за собой много математики и работает достаточно неспешно smile.gif

нашел даже красивый вариант:
http://lua-users.org/lists/lua-l/2004-11/msg00466.html

Но все это тянет математику...

Я готов пожертвовать пару килобайт ПЗУ под таблички для ускорения процесса smile.gif

А моя идея такова:

из IEEE-754 взять показатель степени (2^N), вычислить его в формате К*10^Y и хранить две таблички: K и Y, а вся математика сведется к умножению 2х fixed-point чисел.

Z=A*2^N; 2^N = K*10^Y => Z=A*K*10^Y.

и далее домножать на 10 и вытаскивать из старших разрядов очередную цифру.

только вот мои эксперименты к успешному результату никак не хотят приводить.
(в примере ниже все экспериментально)

Код
typedef union _floats {
  unsigned long u;
  float f;
  struct {
    unsigned ml : 16;
    unsigned mh : 7;
    signed   e  : 8;
    unsigned s  : 1;
  };
} floats;


void convert1 (float in, char *dst)
{
#define shift 24
#define mask 0x00FFFFFF;

  floats intf;
  float lg10;
  floats exp2;
  unsigned long ires;
  unsigned char i;

  intf.f = in;
  exp2.u = 0;                         //заземлить :)
  exp2.e = intf.e;

  exp2.f = log10(exp2.f);         //Ex: 2^-17 = 10^-5.11751
  lg10   = floorf(exp2.f);          //10^-5.11751 = (10^-6)*(10^0.88249)
  exp2.f = exp2.f - lg10;
  exp2.f = powf(10, exp2.f);    //10^.088249 = 7.629395
  
  unsigned long long res, mul1, mul2;

  mul1 = intf.u & 0x00FFFFFF;    //1.23
  mul1 = mul1 | 0x800000;       //set hidden "1"
  mul1 = mul1 << 1;                //1.24

  mul2 = exp2.u & 0x00FFFFFF;  //1.23
  mul2 = mul2 | 0x800000;       //set hidden "1"
  mul2 = mul2 << 1;                //1.24

  res = mul1 * mul2;                //целая часть IN [1,2,...,9]
  ires = res >> 24;

   ires = ires * 10;
  i = ires >> shift;
  *dst++ = i + '0';
  
  *dst++ = '.';

  ires &= mask;
  ires = ires * 10;
  i = ires >> shift;
  *dst++ = i + '0';

  ires &= mask;
  ires = ires * 10;
  i = ires >> shift;
  *dst++ = i + '0';
}


Где ж все-таки собака порылась ?

Эти чудеса нацелены на PIC24.
(меня устраивает, что это только для чисел одинарной точности, не универсально; нечисла мне по барабану)
Прикрепленные файлы
Прикрепленный файл  Table2Calc.rar ( 19.64 килобайт ) Кол-во скачиваний: 51
 
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 08:36
Рейтинг@Mail.ru


Страница сгенерированна за 0.01367 секунд с 7
ELECTRONIX ©2004-2016