Jump to content

    

Recommended Posts

Подскажите средство (макрос?), если таковое имеется, для вычисления квадратного корня во время компиляции.

Имеется:

#define SOME_TRESHOLD  0.15

нужно, чтобы в выражение типа:

if (x < (u32)(SQRT(1 - SOME_TRESHOLD) * (1u << 31))) {...}

компилятор подставил готовую константу. Вместо вычисления её в run-time.

 

PS: Если имеет значение - IAR. Но лучше компиляторо-независимо.

PPS: Пока приходит в голову только: воротить в макросе Ньютона-Рафсона врукопашную. Но может есть путь попроще?

Share this post


Link to post
Share on other sites

на счёт IARa не совсем уверен. но GCC догадался посчитать константу сам и без constexptr

#define SOME_TRESHOLD  0.15
#define SOME_VALUE ((uint32_t)(sqrt(1 - SOME_TRESHOLD) * (1u << 31)))
int main(){
  return SOME_VALUE;
}
 
mov    eax,0x76029a70
ret   

чтобы полностью компиляторнонезависимо, на маркосах руками считать такое совсем грустно, хотя бы шаблоны
https://www.informit.com/articles/article.aspx?p=30667&seqNum=3

ну или внешний скрипт для генерации constant.h

Share this post


Link to post
Share on other sites
32 минуты назад, Arlleex сказал:

У Вас же C++-компилятор? Возможно, определение constexpr-функции, поможет.

Спасибо! Будет время - почитаю.

Пока забабахал макрос Ньютоном-Рафсоном:

#define SQRT_ITER(x, y) (y * (1.5f - y * y * x))
#define SQRT(x) ((x) * \
  SQRT_ITER((x) * .5,  \
  SQRT_ITER((x) * .5,  \
  SQRT_ITER((x) * .5,  \
  SQRT_ITER((x) * .5,  \
  SQRT_ITER((x) * .5,  \
  SQRT_ITER((x) * .5, (((x) - 1.) / 2 + 1))))))))

6 итераций: на диапазоне x=0.6...1.4 получаю точность = 30+ бит.   :wink:

(меня вобщем-то только этот диапазон x-ов интересует, но если кто предложит метод вычисления начального приближения получше чем тут, то - спасибо заранее)

2 минуты назад, _pv сказал:

на счёт IARa не совсем уверен. но GCC догадался посчитать константу сам и без constexptr

Я это сразу проверил. Нет - IAR и для sqrt() и для sqrtf() генерит код run-time вычисления.  :sad:

2 минуты назад, _pv сказал:
чтобы полностью компиляторнонезависимо, на маркосах руками считать такое совсем грустно, хотя бы шаблоны

Да вроде неплохо получилось. :good3:  30 бит мне хватит вполне.

5 минут назад, _pv сказал:

ну или внешний скрипт для генерации constant.h

Громоздко как-то.....

Share this post


Link to post
Share on other sites
4 hours ago, jcxz said:

Подскажите средство (макрос?), если таковое имеется, для вычисления квадратного корня во время компиляции.

Не знаю, в каком диапазоне у Вас меняется аргумент SOME_TRESHOLD  , но пусть от 0.1 до 1.0. Сгенерите таблицу квадратных корней в lookup таблицу, затем домножайте аргумент на 100 (в рантайме будет быстрее, чем вычислить корень), а можно и сразу умноженный записать. Затем, выбирайте из таблицы получившимся индексом...

Ну это так, на гране полушутки...)))

Вы уж не серчайте, но это на фоне темы об "эффективном программировании" от Си-плюс-плюс-водов))))

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.