Беру следующим образом (итеррациями):
Если (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);
// {
// 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]; /* В старшем байте искомый результат */
}
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]; /* В старшем байте искомый результат */
}