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

 
 
> Корень квадратный, Как взять быстро?
lamerok
сообщение Dec 25 2004, 17:52
Сообщение #1


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

Группа: Свой
Сообщений: 135
Регистрация: 22-06-04
Из: Челябинск
Пользователь №: 88



У меня такая проблема. Кварц 32768. Проц должен за 300 мс найти корень из целого числа (X) в диапазоне от 625 до 10000. Нужно получить корень но с точностью два занака, т.е например, корень(1000)= 31.62 = (3162)
Беру следующим образом (итеррациями):
Если (X<=2500) то итерации такие (y1 =) y + (X - y^2)
Если (X>2500), то такие (y1 =) y + (X - y^2)/2.
Вроде считает правильно, но самое максимальное получается 13 итераций. в итоге занимает примерно 850 мс. Очень долго.
Посмотрел, оказалось, что больше всего занимает место перемножение двух 16 рарядных целых чисел(квадрат y^2). примерно 450 циклов в каждой итеррации.
Не подскажите как можно квадрат сделать в циклов 100. или как корень побыстрее сделать.
Использую PIC16.
Пробывал по другому
Код
do
//  {
//      a = b;    
//      b = (a + c/a)/2;
//  } while (a > b);

Получается секунды 2. Из-за того, что все числа long int;

Заранее спасибо
Код
               typedef unsigned char  tU8;  /* 8 bits, unsigned */
    typedef signed char  tS8;  /* 8 bits, unsigned */
    typedef unsigned int  tU16;    /* Two-byte unsigned int */
    typedef long int  tS32;
    typedef signed int  tS16;    /* Two-byte signed int */
    typedef unsigned long  tU32;    /* Four-byte unsigned */
    typedef union {tU8 Byte[4]; tS16 I[2]; tU32 L;} tAll;

tS16 Sqrt(tS16 value)
{
    
    tAll  a;
    tS16 b;    
    tU8  c;
    tAll temp;

    {
//  c = 10000;
//  c = c*Result;
//  b = c;
//  do
//  {
//      a = b;    
//      b = (a + c/a)/2;
//  } while (a > B);
//    }
//    Result = a;
//    return  Result;

 c = value>>8;                   /*Выделяем старший байт*/
 a.L = value * 429496;        /* домнажаем на 65556*6.5536 для точности */
 b = 1;
 temp.I[0] = a.I[1];
 temp.I[1] = a.I[1];
 while(b>0)
 {
     a.L = (tU32)temp.I[0]*(tU16)temp.I[0];   /*  y^2 */
     b = (temp.I[1] - a.I[1]);                         /* X - y^2 */
     if (c > 9)                                              /* Если больше чем 0x900 */
     {
                    b =b>>2;                                       /* (X - y^2)/2 */
     }      
     temp.I[0]+=b;                                    /* y = y+(X-y^2) или y = y+(X-y^2)/2*/
 };
    }
    a.L = (tU32)temp.I[0] * 10000;           /* Множим на 65536/6.5536 = 10000*/
    return a.I[1]; /* В старшем байте искомый результат */
    
}
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 11th August 2025 - 22:03
Рейтинг@Mail.ru


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