Float to String ?

Кто любит RISC в жизни, заходим, не стесняемся.
Аватара пользователя
B@R5uk
Собутыльник Кота
Сообщения: 2896
Зарегистрирован: Сб ноя 13, 2010 12:53:25
Откуда: приходит весна?

Re: Float to String ?

Сообщение B@R5uk »

Andrew Martin писал(а):Нельзя написать одну универсальную библиотеку и использовать её потом везде, при любом положении фиксированной точки.
Ну, это откровенный обман: положение фиксированной точки легко меняется обычным двоичным сдвигом.
Andrew Martin писал(а):Основная доля float вычислений - операции с мантиссой, которые ничем не отличаются от операций в арифметике с фиксированной точкой.
И опять обман. Основная тяжесть плавающей точки заключается в приведении мантиссы к виду, когда обе точки находятся на одном месте (ещё нужно не забыть добавить ведущую единицу), и затем на обратное привидение. Кроме того куча места и времени тратится на реализацию всевозможных проверок (флоат содержим всякие "особые" числа). При арифметике с фиксированной точкой, если мы хотим сложить, то мы просто складываем. Никаких проверок и приведений, всё быстро и просто. Бывают всякие извращения с арифметикой с насыщением, но это для тех, кто не любит работать, типа тех, кто использует флоат. Обычно программист заранее знает диапазон значений аргументов функции (и прописывает этот диапазон в спецификации на написанную им функцию), поэтому вполне способен реализовать вычисление, где насыщение если и нужно будет, то не на каждом шаге вычислений.
Реклама
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25237
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

Re: Float to String ?

Сообщение КРАМ »

Andrew Martin писал(а): Согласен, пример неудачный. Выше приведен более удачный пример, где без флоатов очень туго - LCF-метр.
Совершенно такой же - неудачный.
Дело не в выводимом диапазоне чисел. Выводится ВСЕГДА ЦЕЛОЕ ЧИСЛО, а запятая просто зажигается в нужном месте (или выбирается размерность единиц индикации).
Но САМ ПРОЦЕСС измерений не позволяет перекрыть значительный динамический диапазон мгновенных значений. И потому требует итераций с изменением элементов схемы коммутациями. Это значит, что АППАРАТНО сдвигается и запятая. То есть сами вычисления никак не требуют флоата.
Реклама
Аватара пользователя
moLCHec
Мявтор!
Сообщения: 825
Зарегистрирован: Вс дек 18, 2005 20:04:42
Откуда: Свердловская обл.
Контактная информация:

Re: Float to String ?

Сообщение moLCHec »

Не знаю куда смотрят модеры, но тема явно превратилась в "int vs float".

PS есть аппоунты по быстрым вычислениям на МК (могу выложить в сундуке если найду) и синусов и тангенсов там хоть целые хоть флоат. Корень дак вообще делением можно вычислить. По поводу универсальности просто решается, делаются переменные в мВ, мА, мОм или мкВ, мкА, мкОм и т.д.
Настоящий кот всегда либо голоден,
либо невыспался ...
Аватара пользователя
Andrew Martin
Вымогатель припоя
Сообщения: 606
Зарегистрирован: Вт июн 25, 2013 18:45:07

Re: Float to String ?

Сообщение Andrew Martin »

КРАМ писал(а):
Andrew Martin писал(а): Согласен, пример неудачный. Выше приведен более удачный пример, где без флоатов очень туго - LCF-метр.
Совершенно такой же - неудачный.
Дело не в выводимом диапазоне чисел. Выводится ВСЕГДА ЦЕЛОЕ ЧИСЛО, а запятая просто зажигается в нужном месте (или выбирается размерность единиц индикации).
Но САМ ПРОЦЕСС измерений не позволяет перекрыть значительный динамический диапазон мгновенных значений. И потому требует итераций с изменением элементов схемы коммутациями. Это значит, что АППАРАТНО сдвигается и запятая. То есть сами вычисления никак не требуют флоата.
Опять общие замечания :roll:
Я вам не о гипотетическом "сферическом коне в вакууме" говорю, а о хорошо работающей конструкции, в прошивке которой используется микрочиповская библиотека для float.

Эта схема LC-метра на основе LM311+PIC16F628A стара как мир, его даже некоторые макеевские товарищи запускали в серию, вы тут уже ничего не добавите.

А коммутаций по диапазонам в схеме как раз нет - одни и те же элементы генератора используются НА ВСЕХ поддиапазонах.
Выше уже писали, что для реализации подобного проекта понадобился бы целочисленный "калькулятор" очень высокой разрядности. Никто не захотел лепить горбатого, оценили вычислительные затраты и решились на флоат.
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
Andrew Martin
Вымогатель припоя
Сообщения: 606
Зарегистрирован: Вт июн 25, 2013 18:45:07

Re: Float to String ?

Сообщение Andrew Martin »

B@R5uk писал(а):Основная тяжесть плавающей точки заключается в приведении мантиссы к виду, когда обе точки находятся на одном месте (ещё нужно не забыть добавить ведущую единицу), и затем на обратное привидение. Кроме того куча места и времени тратится на реализацию всевозможных проверок (флоат содержим всякие "особые" числа).
Здесь уже что посеешь, то и пожнёшь. Для того чтобы не наскакивать на всевозможные NaN-ы и прочие "особые" случаи, не нужно передавать в функции float арифметики что попало.

Нормализация (привЕдение) представляет собой обыкновенный сдвиг мантиссы с инкрементом/декрементом экспоненты, это отнюдь не тяжело и не занимает много времени (по сравнению с умножением или делением мантисс).
Опять же, при правильном подходе нормализация при умножении/делении обычно не требуется.
Узкое место у float это сложение/вычитание, оно значительно проигрывает целочисленной арифметике в скорости, и кроме того, в ситуации когда величины операндов значительно отличаются.

Посмотрите исходники хотя бы микрочиповских библиотек для float - это полезно каждому.
B@R5uk писал(а):При арифметике с фиксированной точкой, если мы хотим сложить, то мы просто складываем. Никаких проверок и приведений, всё быстро и просто.
А если хотим умножить/разделить? Точка никуда не уезжает? :)
Да и от переполнения при сложении/вычитании страховаться всё равно нужно, если вы пишете действительно универсальный код, а не работающий корректно только по нечетным дням первой четверти Луны :)))
А это значит что или наращивать разрядность (чтоб было куда carry складывать), или сдвигать вправо, перемещая "фиксированную" точку и заодно отправляя младшие биты в небытие. Или "насыщать", просто записывая при переполнении максимальное число диапазона.
Реклама
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25237
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

Re: Float to String ?

Сообщение КРАМ »

Andrew Martin писал(а):
КРАМ писал(а): Совершенно такой же - неудачный.
Дело не в выводимом диапазоне чисел. Выводится ВСЕГДА ЦЕЛОЕ ЧИСЛО, а запятая просто зажигается в нужном месте (или выбирается размерность единиц индикации).
Но САМ ПРОЦЕСС измерений не позволяет перекрыть значительный динамический диапазон мгновенных значений. И потому требует итераций с изменением элементов схемы коммутациями. Это значит, что АППАРАТНО сдвигается и запятая. То есть сами вычисления никак не требуют флоата.
Опять общие замечания :roll:
Я вам не о гипотетическом "сферическом коне в вакууме" говорю, а о хорошо работающей конструкции, в прошивке которой используется микрочиповская библиотека для float.
Если Вы не понимаете смысла сказанного, то из этого не следует, что речь шла "о конях"... :)
Если в измерителе вы не видите внешних переключений, то из этого не следует, что их нет...
Достаточно изменять ЧАСТОТУ на которой проводится измерение, либо период измерений.
Вы все не можете никак взять в толк, что:
1. Разрядность первичного источника данных сильно ограничена В ЦЕЛЫХ ЧИСЛАХ. И потому ограничен ДИНАМИЧЕСКИЙ ДИАПАЗОН вычислений. А вычислений в LCF-метре - кот наплакал. Покажите мне такую формулу в алгоритме оного прибора, которая бы при вычислениях в целых числах потребовала бы бОльших вычислительных ресурсов нежели флоат... Это и будет "не конь".
2. Применение кем либо флоатов в некоем проекте не доказывает факта безусловной необходимости, а паче хоть какой то технической целесообразности этого действа. Потому ссылки на разного рода конструкции - ни разу не аргумент.
Тут вообще очень модно приводить в качестве доказательства сентенцию "я так делаю и все работает". Глупости тоже часто работают. Просто потому, что не фатальны для проекта.
Реклама
Аватара пользователя
Andrew Martin
Вымогатель припоя
Сообщения: 606
Зарегистрирован: Вт июн 25, 2013 18:45:07

Re: Float to String ?

Сообщение Andrew Martin »

КРАМ писал(а): Достаточно изменять ЧАСТОТУ на которой проводится измерение, либо период измерений.
Вот это вообще шедевр :)
Напомню, что схема LC - части прибора представляет собой автогенератор, частоту которого измеряет пик.
Частота как раз зависит от параметров катушки и конденсатора контура.
Основная формула расчета ёмкости:

Cx = [(F0/F1)^2 - 1]*C0

C0 - ёмкость эталонного конденсатора (константа)
F0 - измеренная частота при отключенном Cx (измеряется при калибровке нуля)
F1 - измеренная частота при подключенном Cx (а вот здесь диапазон изменения около 6 порядков)
Аватара пользователя
Andrew Martin
Вымогатель припоя
Сообщения: 606
Зарегистрирован: Вт июн 25, 2013 18:45:07

Re: Float to String ?

Сообщение Andrew Martin »

moLCHec писал(а):Не знаю куда смотрят модеры, но тема явно превратилась в "int vs float".
Скорее "О бедном float'е замолвите слово" :))
Аватара пользователя
Myp3ik
Мучитель микросхем
Сообщения: 450
Зарегистрирован: Вс янв 09, 2011 23:05:37
Откуда: СССР

Re: Float to String ?

Сообщение Myp3ik »

int vs float :))
Вложения
IQ Math on the TI TMS320C28x DSP.pdf
(416.2 КБ) 1001 скачивание
Иван Сусанин - первый полупроводник :solder:
Аватара пользователя
B@R5uk
Собутыльник Кота
Сообщения: 2896
Зарегистрирован: Сб ноя 13, 2010 12:53:25
Откуда: приходит весна?

Re: Float to String ?

Сообщение B@R5uk »

О! Myp3ik, спасибо. Отличное наглядное пособие. :music: Впрочем, люди, занимающиеся вычислениями на ПК (не на МК!) должны знать такие вещи на зубок. Простой пример: чтобы посчитать разность квадратов с плавающей точкой

с = a^2 - b^2

необходимо производить вычисления следующим образом:

с = (a + b) * (a - b)

иначе точность результата будет заметно похерена. Как приятный бонус вторая формула обеспечивает большее быстродействие (два сложения и одно умножения против двух умножений и одного сложения) в случае, если выполнение умножения занимает больше времени, чем выполнения сложения. Но быстродействие в таких случаях обычно вторично, главное точность. И таких заморочек с плавающей точкой немерено.

В этом плане арифметика с фиксированной точкой обеспечивает значительную простоту программирования, как бы это ни было парадоксально на первый взгляд.
Аватара пользователя
B@R5uk
Собутыльник Кота
Сообщения: 2896
Зарегистрирован: Сб ноя 13, 2010 12:53:25
Откуда: приходит весна?

Re: Float to String ?

Сообщение B@R5uk »

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

Первый, стандартный (привычный?) заключается в порязрядном собирании десятичного числа начиная со старшей цифры. Этот метод требует деления на цело (остаток вычисляется как следствие). Мне этот метод кажется простым, но медленным.

Второй заключается с двоичной поразрядной сборке десятичного числа. Он требует таблицы двоично-десятичных значений всех разрядов всех степеней двойки и использует в процессе только сложение двоично-десятичных чисел. Этот метод будет работать гораздо быстрее, чем первый, при условии, что МК не поддерживает быстрое аппаратное деление.
The_D
Встал на лапы
Сообщения: 108
Зарегистрирован: Пт июл 06, 2012 14:28:17
Откуда: Россия. г.Смоленск

Re: Float to String ?

Сообщение The_D »

Может кто подскажет реализацию sprintf которая не тянет системные библиотеки и может выводить float? Нашел парочку но там нет такой возможности.
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25237
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

Re: Float to String ?

Сообщение КРАМ »

Andrew Martin писал(а):
КРАМ писал(а): Достаточно изменять ЧАСТОТУ на которой проводится измерение, либо период измерений.
Вот это вообще шедевр :)
Напомню, что схема LC - части прибора представляет собой автогенератор, частоту которого измеряет пик.
Задайте себе вопрос о том, ЧЕМ ИЗМЕРЯЮТ эту самую частоту? :))) :))) :)))
И Вы неожиданно обнаружите, что обычным таймером, либо обычным захватом таймера, либо Reciprocal Counter с масштабированием периода счета.
А все Ваши замечательные 6 порядков легко и непринужденно перекрываются 24 разрядным ЦЕЛЫМ (16777216) с запасом в ДВА десятичных порядка. :))) :tea:
arkhnchul
Друг Кота
Сообщения: 3092
Зарегистрирован: Пн апр 06, 2015 11:01:53
Откуда: москва, уфа

Re: Float to String ?

Сообщение arkhnchul »

The_D писал(а):Может кто подскажет реализацию sprintf которая не тянет системные библиотеки и может выводить float? Нашел парочку но там нет такой возможности.
можно вытащить из stdlibc исходник vfprintf и попробовать выкинуть "ненужное". Но там все равно останется довольно дофига кода, в основном для обработки форматов. Имхо если не нужны все возможности подстановки из printf, то проще нарисовать свою функцию для вывода только строк и также для перевода чего нужно в строку.
Аватара пользователя
B@R5uk
Собутыльник Кота
Сообщения: 2896
Зарегистрирован: Сб ноя 13, 2010 12:53:25
Откуда: приходит весна?

Re: Float to String ?

Сообщение B@R5uk »

The_D, вам много функционала от sprintf надо? Может попробовать реализовать самостоятельно?
Аватара пользователя
Andrew Martin
Вымогатель припоя
Сообщения: 606
Зарегистрирован: Вт июн 25, 2013 18:45:07

Re: Float to String ?

Сообщение Andrew Martin »

Вопрос к адептам фиксированной точки: как лучше всего вычислить 20lg(A), где А - 16-битное беззнаковое?
Нужна точность в одну десятую.
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25237
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

Re: Float to String ?

Сообщение КРАМ »

Есть такое обоснованное мнение, что алгоритм последовательных приближений путем 10 циклов 32 разрядного умножения и сравнения из таблицы с 10 значениями степени 10 (от 0,005 до 5,12) решат проблему.
Естественно, что в таблице будут 32 разрядные числа формата 16.16.
:tea:
Собственно это все мало чем отличается от ранее приведенного алгоритма извлечения корня квадратного.
Аватара пользователя
Andrew Martin
Вымогатель припоя
Сообщения: 606
Зарегистрирован: Вт июн 25, 2013 18:45:07

Re: Float to String ?

Сообщение Andrew Martin »

Вот нашел интересный документ по вычислениям с фиксированной точкой.
Может быть кому-нибудь ещё пригодится.

32 разрядные числа формата 16.16 - это 16 бит на целую часть и 16 на дробную?

Возникает вопрос в каком формате будет результат? Целочисленная часть 20*lg(0xFFFF) = 96 укладывается в 7 бит, сколько при этом должно быть в дробной части?
Если "10 значениями степени 10 (от 0,005 до 5,12)" то имеется в виду 10-битный результат? Но если в этом результате целая часть 7 бит, то на дробную уходит всего 3 бита :dont_know:


x = 20*lg(A)

A - 16-битное беззнаковое.

Если я правильно понял, то вся ваша методика сводится к решению уравнения A = pow(10,x/20) = 10^(x/20) методом подбора сомножителей?

Разложив х

x = x6*2^6+...+x0*1+x(-1)*2^-1+x(-2)*2^-2+...

получим

pow(10,x/20) = pow(10,x6*0.05*2^6)*...*pow(10,x0*0.05*1)*pow(10,x(-1)*0.05*2^-1)*...

И откуда взялись значения 0,005 и 5,12? По разложению их не получается :dont_know:

Получается таблица степеней 10:

pow(10,0.05*2^6)
.
.
.
pow(10,0.05*2^-3)
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25237
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

Re: Float to String ?

Сообщение КРАМ »

Andrew Martin писал(а):
32 разрядные числа формата 16.16 - это 16 бит на целую часть и 16 на дробную?

Возникает вопрос в каком формате будет результат? Целочисленная часть 20*lg(0xFFFF) = 96 укладывается в 7 бит, сколько при этом должно быть в дробной части?
:)
Вы все никак не поймете, что НЕТ НИКАКОЙ ДРОБНОЙ ЧАСТИ при вычислении с фиксированной точкой. Это УСЛОВНОСТЬ.
Если Вам требуется разрешение/точность в 0,1 дБ, это означает, что выходная величина будет не 96, а 960.
Поэтому я и сказал про 10 итераций. По одной на каждый разряд двоичного представления числа 960.
И не 960, а в 20 раз меньше. Потому и таблица от 0,005 до 4,8(5,12). С удвоением аргумента:
10^0,005; 10^0,01; 10^0,02; 10^0,04; 10^0,08; 10^0,16; 10^0,32; 10^0,64; 10^1,28; 10^2,56; 10^5,12. Получится таблица, произведение элементов которой и будет давать величину, которую нужно сравнивать с входным 16 разрядным аргументом
Что касается формата 16.16, то я лишь прикинул, что удвоение разрядности исходного числа позволит получить требуемые 0,1 дБ. Все равно 16 разрядов не хватит, так что следующий шаг - 32 разряда.
Но можете и посчитать. Самая требовательный диапазон вблизи малых значений аргумента (1...10).
Я обычно не заморачиваюсь подобными расчетами, а в Экселе строю таблицу на несколько диапазонов функции. Там и выясняется какой шаг аргумента дает искомый шаг функции.
Аватара пользователя
Andrew Martin
Вымогатель припоя
Сообщения: 606
Зарегистрирован: Вт июн 25, 2013 18:45:07

Re: Float to String ?

Сообщение Andrew Martin »

КРАМ писал(а): Вы все никак не поймете, что НЕТ НИКАКОЙ ДРОБНОЙ ЧАСТИ при вычислении с фиксированной точкой. Это УСЛОВНОСТЬ.
Да здесь как раз всё понятно: 32-разрядный регистр, старшие 16 бит условно считаются целой частью, младшие 16 - это fractional part. В прикреплённом выше документе это разжевано, главное - не потерять двоичную точку при вычислениях, и там показаны все правила. С этой УСЛОВНОСТЬЮ всё же прийдётся считаться при вычислениях.
С этим как раз вопросов нет.
КРАМ писал(а): Если Вам требуется разрешение/точность в 0,1 дБ, это означает, что выходная величина будет не 96, а 960.
Поэтому я и сказал про 10 итераций. По одной на каждый разряд двоичного представления числа 960.
Всё правильно - 963 (если точнее) вполне вписывается в 10 разрядов.
КРАМ писал(а): Что касается формата 16.16, то я лишь прикинул, что удвоение разрядности исходного числа позволит получить требуемые 0,1 дБ. Все равно 16 разрядов не хватит, так что следующий шаг - 32 разряда.
Должно хватить. Нужно пробовать :write:

У меня сейчас вопрос скорее алгоритмический. Как я понимаю, то нужно:

Инициализация:
С = 1;
n = 6;
взять из таблицы наибольшее значение, например, Cn = С6 = pow(10,0.05*2^6);

1) M = С*Сn
2) сравнить M с А
3) если А > M то установить 6-й бит (влево от условной двоичной точки) х в единицу, C = M
4) если A = M, то свершилось чудо и мы получили точное значение х=20lg(A). На этом закругляемся.
5) A < M, устанавливаем 6-й бит x в 0
6) n = n-1
7) если n >= -3 идём на пункт 1

Честно говоря, непривычно подбирать сомножители, да ещё из таблицы.

Цифры из таблицы понял :))


x = 10*20*lg(A)

A = pow(10,x/200)

Тогда младший разряд как раз и получается 10^(1/200) = 10^0.005, а старший 10^(1024/200) = 10^5.12.

Однако очень трудно переварить fixed point :(
Ответить

Вернуться в «ARM»