27. juli 2003 - 20:28
#12
Her er et program der udregner kvadrat rødder. Test programmet udregner roden af 1*1, 2*2 ... 1023*1023 og beregner hvor mange der fejl der er.
Der er fejl på 598 af disse, ønskes der større presision skal man lave tabellerne nn_256 og pow_tab større. Der kan også opnåes lidt færre fejl ved at håndtrimme tabellerne.
Det er mere end 5 år siden jeg arbejdede med det sidst og jeg må indrømme at jeg har glemt hvor tallet 850 kommer fra og hvordan jeg beregnede værdierne i pow_tab.
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define int64 __int64
#define TABLEN 256
#ifdef __GNUC__
#define LLARG "%lld"
#else
#define LLARG "%I64d"
#endif
int64 nn_256[TABLEN];
static int64 pow_tab[256] =
{/* 0 1 2 3 4 5 6 7 8 9 */
/* 000 */ 512, 513, 515, 516, 518, 519, 520, 522, 523, 525,
/* 010 */ 526, 527, 529, 530, 532, 533, 535, 536, 538, 539,
/* 020 */ 540, 540, 543, 545, 546, 548, 549, 551, 552, 554,
/* 030 */ 555, 557, 558, 560, 561, 563, 564, 566, 567, 569,
/* 040 */ 571, 572, 573, 575, 577, 578, 580, 581, 583, 585,
/* 050 */ 586, 588, 589, 591, 593, 595, 596, 597, 599, 601,
/* 060 */ 602, 604, 605, 607, 609, 611, 612, 614, 616, 617,
/* 070 */ 619, 621, 622, 624, 626, 627, 629, 631, 632, 634,
/* 080 */ 636, 638, 639, 641, 643, 644, 646, 648, 650, 652,
/* 090 */ 653, 655, 657, 659, 660, 663, 664, 666, 668, 669,
/* 100 */ 672, 673, 675, 677, 679, 680, 682, 684, 686, 688,
/* 110 */ 690, 692, 693, 695, 697, 699, 700, 703, 705, 707,
/* 120 */ 709, 711, 712, 714, 716, 719, 720, 722, 724, 727,
/* 130 */ 728, 730, 732, 734, 736, 738, 740, 742, 744, 746,
/* 140 */ 748, 750, 752, 754, 756, 758, 760, 762, 764, 766,
/* 150 */ 769, 771, 773, 775, 777, 779, 781, 783, 785, 787,
/* 160 */ 790, 792, 794, 796, 799, 800, 803, 805, 807, 809,
/* 170 */ 811, 813, 816, 818, 820, 823, 825, 827, 828, 831,
/* 180 */ 834, 836, 839, 840, 843, 845, 847, 849, 852, 855,
/* 190 */ 856, 859, 861, 863, 866, 868, 875, 873, 875, 878,
/* 200 */ 880, 882, 885, 887, 890, 892, 895, 897, 899, 902,
/* 210 */ 904, 907, 909, 911, 914, 916, 919, 921, 924, 927,
/* 220 */ 929, 931, 935, 936, 939, 942, 944, 947, 949, 952,
/* 230 */ 954, 956, 960, 962, 965, 967, 970, 973, 975, 978,
/* 240 */ 981, 983, 986, 989, 991, 994, 997, 999, 1002, 1005,
/* 250 */ 1007, 1010, 1013, 1016, 1018, 1020
};
int64 pow2(int64 val)
{
int64 a;
a = val >> 8;
if(a >= 10)
return (pow_tab[val & 0x00FF]) << (a - 9);
return ((int64 )pow_tab[val & 0x00FF] + (9 - a)/2) >> (9 - a);
}
int64 log2(int64 val)
{
int64 n, m;
for(n = 63; !(*(((unsigned char *)&val) + 7)); n -= 8, val <<= 8 );
for(; !(*(((unsigned char *)&val) + 7) & 0x80) && n; n--, val <<= 1);
m = (unsigned int )((val >> 55) & (TABLEN - 1));
return (n << 8) + nn_256[m];
}
int64 MySqrt(int64 val)
{
return pow2(log2(val)/2);
}
int main(void)
{
int64 n;
int64 r1;
int64 c = 0;
int i;
double d;
for(i = 0, d = 1.001953125; i < 256; i++, d += 1.0/256.0)
nn_256[i] = 850*log10(d);
for(n = 1; n < 1024; n++)
{
r1 = MySqrt(n*n);
if(r1 != n)
{
fprintf(stderr, "N: " LLARG " " LLARG "\n", n, r1);
c++;
}
}
printf("Errors: " LLARG " of " LLARG "\nHit enter key to exit\n", c, n);
getchar();
return 0;
}