📄 zio.c
字号:
PRINTF1("0x%lx", (FULL) *hp--); while (--len >= 0) { PRINTF1("%04lx", (FULL) *hp--); }#endif /* BASEB == 32 */}/* * Print an integer value as a binary number. * The special characters 0b appear to indicate the number is binary. *//*ARGSUSED*/voidzprintb(ZVALUE z, long width){ register HALF *hp; /* current word to print */ int len; /* number of halfwords to type */ HALF val; /* current value */ HALF mask; /* current mask */ int didprint; /* nonzero if printed some digits */ int ch; /* current char */ char *str; if (width) { math_divertio(); zprintb(z, 0L); str = math_getdivertedio(); math_fill(str, width); free(str); return; } len = z.len - 1; if (zisneg(z)) PUTCHAR('-'); if ((len == 0) && (*z.v <= (FULL) 1)) { len = '0' + (int)(*z.v); PUTCHAR(len & 0xff); return; } hp = z.v + len; didprint = 0; PUTSTR("0b"); while (len-- >= 0) { val = ((len >= 0) ? *hp-- : *hp); mask = ((HALF)1 << (BASEB - 1)); while (mask) { ch = '0' + ((mask & val) != 0); if (didprint || (ch != '0')) { PUTCHAR(ch & 0xff); didprint = 1; } mask >>= 1; } }}/* * Print an integer value as an octal number. * The number begins with a leading 0 to indicate that it is octal. *//*ARGSUSED*/voidzprinto(ZVALUE z, long width){ register HALF *hp; /* current word to print */ int len; /* number of halfwords to type */#if BASEB == 32 /* Yes, the larger base needs a smaller type! */ HALF num1='0'; /* numbers to type */ HALF num2=(HALF)0; /* numbers to type */ HALF num3; /* numbers to type */ HALF num4; /* numbers to type */#else FULL num1='0'; /* numbers to type */ FULL num2=(FULL)0; /* numbers to type */#endif int rem; /* remainder number of halfwords */ char *str; if (width) { math_divertio(); zprinto(z, 0L); str = math_getdivertedio(); math_fill(str, width); free(str); return; } if (zisneg(z)) PUTCHAR('-'); len = z.len; if ((len == 1) && (*z.v <= (FULL) 7)) { num1 = '0' + (int)(*z.v); PUTCHAR((int)(num1 & 0xff)); return; } hp = z.v + len - 1; rem = len % 3;#if BASEB == 32 switch (rem) { /* handle odd amounts first */ case 0: num1 = ((hp[0]) >> 8); num2 = (((hp[0] & 0xff) << 16) + (hp[-1] >> 16)); num3 = (((hp[-1] & 0xffff) << 8) + (hp[-2] >> 24)); num4 = (hp[-2] & 0xffffff); if (num1) { PRINTF4("0%lo%08lo%08lo%08lo", (PRINT) num1, (PRINT) num2, (PRINT) num3, (PRINT) num4); } else { PRINTF3("0%lo%08lo%08lo", (PRINT) num2, (PRINT) num3, (PRINT) num4); } rem = 3; break; case 1: PRINTF1("0%lo", (PRINT) hp[0]); break; case 2: num1 = ((hp[0]) >> 16); num2 = (((hp[0] & 0xffff) << 8) + (hp[-1] >> 24)); num3 = (hp[-1] & 0xffffff); if (num1) { PRINTF3("0%lo%08lo%08lo", (PRINT) num1, (PRINT) num2, (PRINT) num3); } else { PRINTF2("0%lo%08lo", (PRINT) num2, (PRINT) num3); } break; } len -= rem; if (len > 0) { hp -= rem; while (len > 0) { /* finish in groups of 3 words */ PRINTF4("%08lo%08lo%08lo%08lo", (PRINT) ((hp[0]) >> 8), (PRINT) (((hp[0] & 0xff) << 16) + (hp[-1] >> 16)), (PRINT) (((hp[-1] & 0xffff) << 8) + (hp[-2] >> 24)), (PRINT) (hp[-2] & 0xffffff)); hp -= 3; len -= 3; } }#else switch (rem) { /* handle odd amounts first */ case 0: num1 = ((((FULL) hp[0]) << 8) + (((FULL) hp[-1]) >> 8)); num2 = ((((FULL) (hp[-1] & 0xff)) << 16) + ((FULL) hp[-2])); rem = 3; break; case 1: num1 = 0; num2 = (FULL) hp[0]; break; case 2: num1 = (((FULL) hp[0]) >> 8); num2 = ((((FULL) (hp[0] & 0xff)) << 16) + ((FULL) hp[-1])); break; } if (num1) { PRINTF2("0%lo%08lo", num1, num2); } else { PRINTF1("0%lo", num2); } len -= rem; if (len > 0) { hp -= rem; while (len > 0) { /* finish in groups of 3 halfwords */ PRINTF2("%08lo%08lo", ((((FULL) hp[0]) << 8) + (((FULL) hp[-1]) >> 8)), ((((FULL) (hp[-1] & 0xff))<<16) + ((FULL) hp[-2]))); hp -= 3; len -= 3; } }#endif}/* * Print a decimal integer to the terminal. * This works by dividing the number by 10^2^N for some N, and * then doing this recursively on the quotient and remainder. * Decimals supplies number of decimal places to print, with a decimal * point at the right location, with zero meaning no decimal point. * Width is the number of columns to print the number in, including the * decimal point and sign if required. If zero, no extra output is done. * If positive, leading spaces are typed if necessary. If negative, trailing * spaces are typed if necessary. As examples of the effects of these values, * (345,0,0) = "345", (345,2,0) = "3.45", (345,5,8) = " .00345". * * given: * z number to be printed * decimals number of decimal places * width number of columns to print in */voidzprintval(ZVALUE z, long decimals, long width){ int depth; /* maximum depth */ int n; /* current index into array */ long i; /* number to print */ long leadspaces; /* number of leading spaces to print */ long putpoint; /* digits until print decimal point */ long digits; /* number of digits of raw number */ BOOL output; /* TRUE if have output something */ BOOL neg; /* TRUE if negative */ ZVALUE quo, rem; /* quotient and remainder */ ZVALUE leftnums[32]; /* left parts of the number */ ZVALUE rightnums[32]; /* right parts of the number */ if (decimals < 0) decimals = 0; if (width < 0) width = 0; neg = (z.sign != 0); leadspaces = width - neg - (decimals > 0); z.sign = 0; /* * Find the 2^N power of ten which is greater than or equal * to the number, calculating it the first time if necessary. */ _tenpowers_[0] = _ten_; depth = 0; while ((_tenpowers_[depth].len < z.len) || (zrel(_tenpowers_[depth], z) <= 0)) { depth++; if (_tenpowers_[depth].len == 0) { if (depth <= TEN_MAX) { zsquare(_tenpowers_[depth-1], &_tenpowers_[depth]); } else { math_error("cannot compute 10^2^(TEN_MAX+1)"); /*NOTREACHED*/ } } } /* * Divide by smaller 2^N powers of ten until the parts are small * enough to output. This algorithm walks through a binary tree * where each node is a piece of the number to print, and such that * we visit left nodes first. We do the needed recursion in line. */ digits = 1; output = FALSE; n = 0; putpoint = 0; rightnums[0].len = 0; leftnums[0] = z; for (;;) { while (n < depth) { i = depth - n - 1; zdiv(leftnums[n], _tenpowers_[i], &quo, &rem, 0); if (!ziszero(quo)) digits += (1L << i); n++; leftnums[n] = quo; rightnums[n] = rem; } i = (long)(leftnums[n].v[0]); if (output || i || (n == 0)) { if (!output) { output = TRUE; if (decimals < digits) leadspaces -= digits; else leadspaces -= decimals+conf->leadzero; while (--leadspaces >= 0) PUTCHAR(' '); if (neg) PUTCHAR('-'); if (decimals) { putpoint = (digits - decimals); if (putpoint <= 0) { if (conf->leadzero) PUTCHAR('0'); PUTCHAR('.'); while (++putpoint <= 0) PUTCHAR('0'); putpoint = 0; } } } i += '0'; PUTCHAR((int)(i & 0xff)); if (--putpoint == 0) PUTCHAR('.'); } while (rightnums[n].len == 0) { if (n <= 0) return; if (leftnums[n].len) zfree(leftnums[n]); n--; } zfree(leftnums[n]); leftnums[n] = rightnums[n]; rightnums[n].len = 0; }}/* * Read an integer value in decimal, hex, octal, or binary. * Hex numbers are indicated by a leading "0x", binary with a leading "0b", * and octal by a leading "0". Periods are skipped over, but any other * extraneous character stops the scan. */voidstr2z(char *s, ZVALUE *res){ ZVALUE z, ztmp, digit; HALF digval; BOOL minus; long shift; minus = FALSE; shift = 0; if (*s == '+') s++; else if (*s == '-') { minus = TRUE; s++; } if (*s == '0') { /* possibly hex, octal, or binary */ s++; if ((*s >= '0') && (*s <= '7')) { shift = 3; } else if ((*s == 'x') || (*s == 'X')) { shift = 4; s++; } else if ((*s == 'b') || (*s == 'B')) { shift = 1; s++; } } digit.v = &digval; digit.len = 1; digit.sign = 0; z = _zero_; while (*s) { digval = *s++; if ((digval >= '0') && (digval <= '9')) digval -= '0'; else if ((digval >= 'a') && (digval <= 'f') && shift) digval -= ('a' - 10); else if ((digval >= 'A') && (digval <= 'F') && shift) digval -= ('A' - 10); else if (digval == '.') continue; else break; if (shift) zshift(z, shift, &ztmp); else zmuli(z, 10L, &ztmp); zfree(z); zadd(ztmp, digit, &z); zfree(ztmp); } ztrim(&z); if (minus && !ziszero(z)) z.sign = 1; *res = z;}voidfitzprint(ZVALUE z, long digits, long show){ ZVALUE ztmp1, ztmp2; long i; if (digits <= show) { zprintval(z, 0, 0); return; } show /= 2; ztenpow(digits - show, &ztmp1); (void) zquo(z, ztmp1, &ztmp2, 1); zprintval(ztmp2, 0, 0); zfree(ztmp1); zfree(ztmp2); printf("..."); ztenpow(show, &ztmp1); (void) zmod(z, ztmp1, &ztmp2, 0); i = zdigits(ztmp2); while (i++ < show) printf("0"); zprintval(ztmp2, 0, 0); zfree(ztmp1); zfree(ztmp2);}/* END CODE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -