Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Keil mVision2 RV
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Sart
Здравствуйте.
Подскажите как armlink заставить изменить режим округления числа с плавающей точкой?
VAI
Вы можете сформулировать вопрос более грамотно.
Наверное Вы не совсем понимаете, что делает линкер...
Sart
В Help я вычитал следующее:

"Note
The standard fplib libraries f* support only the Round to nearest rounding mode. If you require support for the other rounding modes, you must use the full IEEE g* libraries. See Library naming conventions."

Пошел смотреть Library naming conventions.

"Normally, you do not have to list any of these libraries explicitly on the linker command line. The ARM linker automatically selects the correct C or C++ libraries to use, and it might use several, based on the accumulation of the object attributes.

If library names are explicitly named in a makefile, you must rebuild your project as follows:

Remove the explicit references to the old library names from the linker command‑line.

Add ‑‑info libraries to the linker command‑line and rebuild the project. This produces a list of all the libraries in use.

Add the new list of libraries to the linker command‑line."

Но вот как конкретно выполнить эти инструкции я никак не пойму?
Подскажите, где я ошибаюсь или не понимаю, а лучше что конкретно сделать?
aaarrr
Для подключения полных библиотек достаточно в опциях проекта на вкладке C/C++ в поле Misc controls дописать "--fpmode=ieee_full".
Sart
Большое спасибо. А подскажите еще как указать до какого знака после запятой округлять? Буду очень признателен.
aaarrr
Тек-с. Вообще-то к какому-либо знаку после запятой это округление не относится:
Цитата
Arithmetic is generally performed by computing the result of an operation as if it were stored exactly (to infinite precision), and then rounding it to fit in the format. Apart from operations whose result already fits exactly into the format (such as adding 1.0 to 1.0), the correct answer is generally somewhere between two representable numbers in the format. The system then chooses one of these two numbers as the rounded result.


Задачу озвучте.
Sart
Проблема вот в чем:

В программе переменной типа float присваивается значение 0.1. Но вместо 0.1 реально после 9-го знака после запятой появляются цифры. В программе эта переменная является приращением некоторой величины. Но так как она не равна ровно 0.1 не выполняется условие if (величина == 5.0). Хотелось бы как то получить все таки ровно 0.1.
aaarrr
В плавающей точке ровно обычно ничего не бывает. Поэтому использовать сравнения типа if(величина == 5.0) нельзя.
Sart
Соглашусь с Вами. Но как то указать компилятору что нужно округлять скажем до 3-го знака можно?
aaarrr
Нет, можно только округлить вручную или придумать другое условие для сравнения.
Alexandro
Может это поможет:

убрать мусор из float

from: http://caxapa.ru/79045.html

Данный странный алгоритм убирает мусор из числа. Известно заранее, что числа "правильные" в некотором смысле.
Например - шаг шкалы оцифровки графика.

// Жила была переменная float
float Step=0.1; // или 1./3. или 2./3. или что нибудь похожее

// Её копируют в double, в результате в младших разрядах мусор 0.100000001490116 , 0.333333343267441 ...
double StepD=Step;

//Но мусор нам не нужен и его убираем
unsigned char *p=(unsigned char *)&StepD;
if(p[4]==p[5]) p[0]=p[1]=p[2]=p[3]=p[4];

// В результате получаем 0.1, 0.333333333333333 ...

Алгоритм используется в реальном проекте. Выглядит странно, но очень эфективен.
scifi
Цитата(Sart @ Oct 9 2008, 09:22) *
Соглашусь с Вами. Но как то указать компилятору что нужно округлять скажем до 3-го знака можно?

ИМХО, это не есть работа компилятора.
Просто напишите if (fabs(val - 5.0f) < 0.001f) { ... }
VAI
Цитата
А подскажите еще как указать до какого знака после запятой округлять? Буду очень признателен.

Код

/* --- round() -------------------------------------------------------------------------------------------- **
*  value    - что округлять
*  accuracy - с какой точностью округлять
* -------------------------------------------------------------------------------------------------------- */
float round( float value, float accuracy )
{
  return( ((long)( value / accuracy + ( value < (float)0.0 ? (float)-0.5 : (float)0.5 ))) * accuracy );
}

accuracy - с какой точностью округлять:
0.01 - результат работы функции будет кратен 0.01, после запятой будет только 2 цифры.
0.024 - результат работы функции будет кратен 0.024, после запятой будет только 3 цифры.
Sart
Я наверное неправильно выразился. Нужно как то указать компилятору сколько знаков после десятичной точки должно быть в числе.

В файле float.h определены дефайны вроде бы отвечающие за это. Поигрался с ними, но никаких изменнений не произошло.
aaarrr
Цитата(Sart @ Oct 9 2008, 14:39) *
Я наверное неправильно выразился. Нужно как то указать компилятору сколько знаков после десятичной точки должно быть в числе.

Этого сделать нельзя.

Цитата(Sart @ Oct 9 2008, 14:39) *
В файле float.h определены дефайны вроде бы отвечающие за это. Поигрался с ними, но никаких изменнений не произошло.

В этом файле перечислены параметры и пределы при работе с плавающей точкой, менять там что-либо бесполезно.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.