#include main() { unsigned r0, r1, r2, r3, r4, r5, r6, s0, s1; unsigned t0, t1, t2, t3, cycle, f, incorrect, spup; unsigned thr_m2_m1, thr_m1_0, thr_0_1, thr_1_2, positive, errornum; char line[30], *linepoint; r0 = 0x0bffffc0; r1 = 0; r2 = 0x0800bf60; r3 = 0; printf("First digit of mantissas must be between 8 and f\n"); printf("Enter dividend mantissa in hex: "); *(line+15) = '0'; scanf("%s", line); linepoint = line; while (*linepoint != '\0') linepoint++; while (linepoint < line + 15) *linepoint++ = '0'; *(line+16) = '\0'; sscanf(line+15, "%x", &spup); spup = (spup >> 2) | (12 & (spup << 2)); *(line+15) = '\0'; sscanf(line+7, "%x", &r3); *(line+7) = '\0'; sscanf(line, "%x", &r2); printf("Enter divisor mantissa in hex: "); scanf("%s", line); linepoint = line; while (*linepoint != '\0') linepoint++; while (linepoint < line + 15) *linepoint++ = '0'; *(line+15) = '\0'; sscanf(line+7, "%x", &r1); *(line+7) = '\0'; sscanf(line, "%x", &r0); r4 = 0; r5 = 0; t0 = r2; while (!(t0 & 1)) t0 = t0 >> 1; printf("%d\n", t0); t0 = r0; while (!(t0 & 1)) t0 = t0 >> 1; printf("%d\n", t0); /* These thresholds are VERY tentative. */ /* There may be bugs in them. */ t0 = r0 >> 22; /* Next threshold is strongly indicated */ /* by the failure of 1/9895574626641 */ if (t0 < 36) thr_0_1 = 3; /* Next threshold is strongly indicated */ /* by the failure of 1/824633702441 */ else if (t0 < 48) thr_0_1 = 4; /* Next threshold is strongly indicated */ /* by the failure of 5244795/3932159 */ else if (t0 < 60) thr_0_1 = 5; else thr_0_1 = 6; thr_m1_0 = 254 - thr_0_1; if (t0 < 33) thr_1_2 = 11; else if (t0 < 34) { printf("This model does not correctly handle\n"); printf("this divisor. The Pentium divider\n"); printf("undoubtly handles this divisor correctly\n"); printf("by some means that I have no evidence\n"); printf("upon which speculate.\n"); exit(); } /* Next threshold is strongly indicated */ /* by the failure of 41.999999/35.9999999 */ else if (t0 < 36) thr_1_2 = 12; else if (t0 < 39) thr_1_2 = 13; /* Next threshold is strongly indicated */ /* by the failure of 1/1443107810341 and */ /* by the failure of 48.999999/41.9999999 */ else if (t0 < 42) thr_1_2 = 14; else if (t0 < 44) thr_1_2 = 15; /* Next threshold is strongly indicated */ /* by the failure of 55.999999/47.9999999 */ else if (t0 < 48) thr_1_2 = 16; /* Next threshold is strongly indicated */ /* by the failure of 62.999999/53.9999999 */ else if (t0 < 54) thr_1_2 = 18; /* Next threshold is strongly indicated */ /* by the failure of 54.999999/59.9999999 */ else if (t0 < 60) thr_1_2 = 20; else thr_1_2 = 23; thr_m2_m1 = 254 - thr_1_2; if (t0 == 35) errornum = 22; else if (t0 == 41) errornum = 26; else if (t0 == 47) errornum = 30; else if (t0 == 53) errornum = 34; else if (t0 == 59) errornum = 38; else errornum = 128; incorrect = 0; cycle = 1; /* The cycle limit would be ~34 instead of */ /* 18 for double extended precision. */ while (cycle < 18) { t0 = 255 & ((r2 >> 24) + (r4 >> 24)); if ((t0 > thr_m1_0) || (t0 < thr_0_1)) { s0 = 0; s1 = 0; positive = 0; printf("next digit 0\n"); } else if (t0 > thr_m2_m1) { s0 = r0; s1 = r1; positive = 0; printf("next digit -1\n"); } else if (t0 < thr_1_2) { s0 = ~r0; s1 = ~r1; positive = 4; printf("next digit 1\n"); } else if (t0 & 128) { s0 = (r0 << 1) | (r1 >> 31); s1 = r1 << 1; positive = 0; printf("next digit -2\n"); } else { s0 = ~((r0 << 1) | (r1 >> 31)); s1 = ~(r1 << 1); positive = 4; printf("next digit 2\n"); if ((t0 == errornum) && (((r2 >> 21) & 7) == 7) && (((r4 >> 21) & 7) == 7)) { printf("A bug condition has been detected.\n"); printf("Enter 0 for correct result or 1 for incorrect result: "); scanf("%d", &incorrect); if (incorrect) { /* These amounts that are subtracted from the */ /* remainder have NOT been extensively verified. */ if (errornum == 22) s0 = s0 - (3 << 25); else s0 = s0 - (4 << 25); } } } t0 = s0 ^ r2 ^ r4; t1 = s1 ^ r3 ^ r5; t2 = (s0 & r2) | (s0 & r4) | (r2 & r4); t3 = (s1 & r3) | (s1 & r5) | (r3 & r5); r2 = (t0 << 2) | (t1 >> 30); r3 = t1 << 2; r4 = (t2 << 3) | (t3 >> 29); r5 = (t3 << 3) | positive | (spup & 3); spup = spup >> 2; t0 = r2; f = 32; while (f--) { if (t0 & (1 << 31)) putchar('1'); else putchar('0'); t0 = t0 << 1; } t0 = r3; f = 32; while (f--) { if (t0 & (1 << 31)) putchar('1'); else putchar('0'); t0 = t0 << 1; } putchar('\n'); t0 = r4; f = 32; while (f--) { if (t0 & (1 << 31)) putchar('1'); else putchar('0'); t0 = t0 << 1; } t0 = r5; f = 32; while (f--) { if (t0 & (1 << 31)) putchar('1'); else putchar('0'); t0 = t0 << 1; } putchar('\n'); t0 = r2 + r4; f = 32; while (f--) { if (t0 & (1 << 31)) putchar('1'); else putchar('0'); t0 = t0 << 1; } printf(" iteration number %d\n", cycle++); } }
“This error is the most insidious: it is almost as insidious as if it didn’t alarm the people at all when they viewed the columns of their data. Thus, tiny errors in one thousandth of thousands of times can get into trillions of calculations all over the world for a long time, and there is almost no way to determine them except by performing a massive error check in FPU, which is absolutely not necessary for a reliably working processor. "
#include #include main(argc, argv) char *argv[]; { int i, j, cnt, digits; double prec, tol, ibruis, jbruis, pent, true; for (digits = 15, prec = 1e-15; digits > 2; digits--, prec *= 10) { printf("%4.d\t\t", digits); for (tol = 1e-15; tol < 1e-4; tol *= 100) { cnt = 0; for (i = 1; i <= 1000; i++) for (j = 1; j <= 1000; j++) { ibruis = i - prec, jbruis = j - prec; pent = ibruis/jbruis; true = (1.11*ibruis)/(1.11*jbruis); cnt += (fabs(pent - true) > tol*true); } printf("%4d ", cnt); } printf("\n"); } }
Source: https://habr.com/ru/post/314534/
All Articles