⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpcalc.c

📁 纯C数据结构
💻 C
字号:
#include <ctype.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <limits.h>#include "mem.h"#include "seq.h"#include "fmt.h"#include "mp.h"Seq_T sp;int ibase = 10;int obase = 10;struct {	char *fmt;	MP_T (*add)(MP_T, MP_T, MP_T);	MP_T (*sub)(MP_T, MP_T, MP_T);	MP_T (*mul)(MP_T, MP_T, MP_T);	MP_T (*div)(MP_T, MP_T, MP_T);	MP_T (*mod)(MP_T, MP_T, MP_T);} s = { "%D\n",	MP_add,  MP_sub,  MP_mul,  MP_div,  MP_mod  },  u = { "%U\n",	MP_addu, MP_subu, MP_mulu, MP_divu, MP_modu }, *f = &s;MP_T pop(void) {	if (Seq_length(sp) > 0)		return Seq_remhi(sp);	else {		Fmt_fprint(stderr, "?stack underflow\n");		return MP_new(0);	}}int main(int argc, char *argv[]) {	int c;	sp = Seq_new(0);	Fmt_register('D', MP_fmt);	Fmt_register('U', MP_fmtu);	while ((c = getchar()) != EOF) {		MP_T x = NULL, y = NULL, z = NULL;		TRY 			switch (c) {			default:				if (isprint(c))					Fmt_fprint(stderr, "?'%c'", c);				else					Fmt_fprint(stderr, "?'\\%03o'", c);				Fmt_fprint(stderr, " is unimplemented\n");				break;			case ' ': case '\t': case '\n': case '\f': case '\r':				break;			case 'c': while (Seq_length(sp) > 0) {				  	MP_T x = Seq_remhi(sp);				  	FREE(&x);				  } break;			case 'q': while (Seq_length(sp) > 0) {				  	MP_T x = Seq_remhi(sp);				  	FREE(&x);				  }				  Seq_free(&sp);				  return EXIT_SUCCESS;			case '0': case '1': case '2': case '3': case '4':			case '5': case '6': case '7': case '8': case '9': {				char buf[512];				z = MP_new(0);				{					int i = 0;					for ( ;  strchr(&"zyxwvutsrqponmlkjihgfedcba9876543210"[36-ibase],							tolower(c)); c = getchar(), i++)						if (i < (int)sizeof (buf) - 1)							buf[i] = c;					if (i > (int)sizeof (buf) - 1) {						i = (int)sizeof (buf) - 1;						Fmt_fprint(stderr,							"?integer constant exceeds %d digits\n", i);					}					buf[i] = '\0';					if (c != EOF)						ungetc(c, stdin);				}				MP_fromstr(z, buf, ibase, NULL);				break;			}			case '+': y = pop(); x = pop();				  z = MP_new(0); (*f->add)(z, x, y); break;			case '-': y = pop(); x = pop();				  z = MP_new(0); (*f->sub)(z, x, y); break;			case '*': y = pop(); x = pop();				  z = MP_new(0); (*f->mul)(z, x, y); break;			case '/': y = pop(); x = pop();				  z = MP_new(0); (*f->div)(z, x, y); break;			case '%': y = pop(); x = pop();				  z = MP_new(0); (*f->mod)(z, x, y); break;			case '&': y = pop(); x = pop();				  z = MP_new(0);    MP_and(z, x, y); break;			case '|': y = pop(); x = pop();				  z = MP_new(0);    MP_or (z, x, y); break;			case '^': y = pop(); x = pop();				  z = MP_new(0);    MP_xor(z, x, y); break;			case '!': z = pop(); MP_not(z, z); break;			case '~': z = pop(); MP_neg(z, z); break;			case 'i': case 'o': {				long n;				x = pop();				n = MP_toint(x);				if (n < 2 || n > 36)					Fmt_fprint(stderr, "?%d is an illegal base\n",n);				else if (c == 'i')					ibase = n;				else					obase = n;				if (obase == 2 || obase == 8 || obase == 16)					f = &u;				else					f = &s;				break;				}			case 'p':				Fmt_print(f->fmt, z = pop(), obase);				break;			case 'f': {				int n = Seq_length(sp);				while (--n > 0)					Fmt_print(f->fmt, Seq_get(sp, n), obase);				break;			}			case '<': { long s;				    y = pop();				    z = pop();				    s = MP_toint(y);				    if (s < 0 || s > INT_MAX) {				    	Fmt_fprint(stderr,				    		"?%d is an illegal shift amount\n", s);				    	break;				    }; MP_lshift(z, z, s); break; }			case '>': { long s;				    y = pop();				    z = pop();				    s = MP_toint(y);				    if (s < 0 || s > INT_MAX) {				    	Fmt_fprint(stderr,				    		"?%d is an illegal shift amount\n", s);				    	break;				    }; MP_rshift(z, z, s); break; }			case 'k': {				long n;				x = pop();				n = MP_toint(x);				if (n < 2 || n > INT_MAX)					Fmt_fprint(stderr,						"?%d is an illegal precision\n", n);				else if (Seq_length(sp) > 0)					Fmt_fprint(stderr, "?nonempty stack\n");				else					MP_set(n);				break;				}			case 'd': {				MP_T x = pop();				z = MP_new(0);				Seq_addhi(sp, x);				MP_addui(z, x, 0);				break;				}			}		EXCEPT(MP_Overflow)			Fmt_fprint(stderr, "?overflow\n");		EXCEPT(MP_Dividebyzero)			Fmt_fprint(stderr, "?divide by 0\n");		END_TRY;		if (z)			Seq_addhi(sp, z);		FREE(&x);		FREE(&y);	}	while (Seq_length(sp) > 0) {		MP_T x = Seq_remhi(sp);		FREE(&x);	}	Seq_free(&sp);	return EXIT_SUCCESS;}static char rcsid[] = "$RCSfile: RCS/mp.doc,v $ $Revision: 1.8 $";

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -