slcmplex.c

来自「一个C格式的脚本处理函数库源代码,可让你的C程序具有执行C格式的脚本文件」· C语言 代码 · 共 1,143 行 · 第 1/2 页

C
1,143 行
字号
	     c[n + 1] = a[1];	     a += da; b += db;	  }	break;      case SLANG_TIMES:	for (n = 0; n < n_max; n += 2)	  {	     double b0 = b[0];	     c[n] = a[0] * b0;	     c[n + 1] = a[1] * b0;	     a += da; b += db;	  }	break;      case SLANG_DIVIDE:	       /* / */	for (n = 0; n < n_max; n += 2)	  {	     double b0 = b[0];	     if (b0 == 0.0)	       {		  SLang_Error = SL_DIVIDE_ERROR;		  return -1;	       }	     c[n] = a[0] / b0;	     c[n + 1] = a[1] / b0;	     a += da; b += db;	  }	break;      case SLANG_EQ: 		       /* == */	for (n = 0; n < n_max; n += 2)	  {	     ic[n/2] = ((a[0] == b[0]) && (a[1] == 0.0));	     a += da; b += db;	  }	break;      case SLANG_NE:		       /* != */	for (n = 0; n < n_max; n += 2)	  {	     ic[n/2] = ((a[0] != b[0]) || (a[1] != 0.0));	     a += da; b += db;	  }	break;      case SLANG_POW:	for (n = 0; n < n_max; n += 2)	  {	     complex_dpow (c + n, a, b[0]);	     a += da; b += db;	  }	break;     }   return 1;}static int double_complex_binary (int op,				  unsigned char a_type, VOID_STAR ap, unsigned int na,				  unsigned char b_type, VOID_STAR bp, unsigned int nb,				  VOID_STAR cp){   char *ic;   double *a, *b, *c;   unsigned int n, n_max;   unsigned int da, db;   (void) a_type;   (void) b_type;   a = (double *) ap;   b = (double *) bp;   c = (double *) cp;   ic = (char *) cp;   if (na == 1) da = 0; else da = 1;   if (nb == 1) db = 0; else db = 2;   if (na > nb) n_max = na; else n_max = nb;   n_max = 2 * n_max;   switch (op)     {      default:	return 0;      case SLANG_PLUS:	for (n = 0; n < n_max; n += 2)	  {	     c[n] = a[0] + b[0];	     c[n + 1] = b[1];	     a += da; b += db;	  }	break;      case SLANG_MINUS:	for (n = 0; n < n_max; n += 2)	  {	     c[n] = a[0] - b[0];	     c[n + 1] = -b[1];	     a += da; b += db;	  }	break;      case SLANG_TIMES:	for (n = 0; n < n_max; n += 2)	  {	     double a0 = a[0];	     c[n] = a0 * b[0];	     c[n + 1] = a0 * b[1];	     a += da; b += db;	  }	break;      case SLANG_DIVIDE:	       /* / */	for (n = 0; n < n_max; n += 2)	  {	     double z[2];	     if ((b[0] == 0.0) && (b[1] == 0.0))	       {		  SLang_Error = SL_DIVIDE_ERROR;		  return -1;	       }	     z[0] = a[0];	     z[1] = 0.0;	     SLcomplex_divide (c + n, z, b);	     a += da; b += db;	  }	break;      case SLANG_EQ: 		       /* == */	for (n = 0; n < n_max; n += 2)	  {	     ic[n/2] = ((a[0] == b[0]) && (0.0 == b[1]));	     a += da; b += db;	  }	break;      case SLANG_NE:		       /* != */	for (n = 0; n < n_max; n += 2)	  {	     ic[n/2] = ((a[0] != b[0]) || (0.0 != b[1]));	     a += da; b += db;	  }	break;      case SLANG_POW:	for (n = 0; n < n_max; n += 2)	  {	     dcomplex_pow (c + n, a[0], b);	     a += da; b += db;	  }	break;     }   return 1;}static int complex_generic_binary (int op,				   unsigned char a_type, VOID_STAR ap, unsigned int na,				   unsigned char b_type, VOID_STAR bp, unsigned int nb,				   VOID_STAR cp){   char *ic;   char *b;   double *a, *c;   unsigned int n, n_max;   unsigned int da, db;   unsigned int sizeof_b;   SLang_To_Double_Fun_Type to_double;   if (NULL == (to_double = SLarith_get_to_double_fun (b_type, &sizeof_b)))     return 0;   (void) a_type;   a = (double *) ap;   b = (char *) bp;   c = (double *) cp;   ic = (char *) cp;   if (na == 1) da = 0; else da = 2;   if (nb == 1) db = 0; else db = sizeof_b;   if (na > nb) n_max = na; else n_max = nb;   n_max = 2 * n_max;   switch (op)     {      default:	return 0;      case SLANG_POW:	for (n = 0; n < n_max; n += 2)	  {	     complex_dpow (c + n, a, to_double((VOID_STAR)b));	     a += da; b += db;	  }	break;      case SLANG_PLUS:	for (n = 0; n < n_max; n += 2)	  {	     c[n] = a[0] + to_double((VOID_STAR)b);	     c[n + 1] = a[1];	     a += da; b += db;	  }	break;      case SLANG_MINUS:	for (n = 0; n < n_max; n += 2)	  {	     c[n] = a[0] - to_double((VOID_STAR)b);	     c[n + 1] = a[1];	     a += da; b += db;	  }	break;      case SLANG_TIMES:	for (n = 0; n < n_max; n += 2)	  {	     double b0 = to_double((VOID_STAR)b);	     c[n] = a[0] * b0;	     c[n + 1] = a[1] * b0;	     a += da; b += db;	  }	break;      case SLANG_DIVIDE:	       /* / */	for (n = 0; n < n_max; n += 2)	  {	     double b0 = to_double((VOID_STAR)b);	     if (b0 == 0)	       {		  SLang_Error = SL_DIVIDE_ERROR;		  return -1;	       }	     c[n] = a[0] / b0;	     c[n + 1] = a[1] / b0;	     a += da; b += db;	  }	break;      case SLANG_EQ: 		       /* == */	for (n = 0; n < n_max; n += 2)	  {	     ic[n/2] = ((a[0] == to_double((VOID_STAR)b)) && (a[1] == 0.0));	     a += da; b += db;	  }	break;      case SLANG_NE:		       /* != */	for (n = 0; n < n_max; n += 2)	  {	     ic[n/2] = ((a[0] != to_double((VOID_STAR)b)) || (a[1] != 0.0));	     a += da; b += db;	  }	break;     }   return 1;}static int generic_complex_binary (int op,				   unsigned char a_type, VOID_STAR ap, unsigned int na,				   unsigned char b_type, VOID_STAR bp, unsigned int nb,				   VOID_STAR cp){   double *b, *c;   char *a, *ic;   unsigned int n, n_max;   unsigned int da, db;   unsigned int sizeof_a;   SLang_To_Double_Fun_Type to_double;   if (NULL == (to_double = SLarith_get_to_double_fun (a_type, &sizeof_a)))     return 0;   (void) b_type;   a = (char *) ap;   b = (double *) bp;   c = (double *) cp;   ic = (char *) cp;   if (na == 1) da = 0; else da = sizeof_a;   if (nb == 1) db = 0; else db = 2;   if (na > nb) n_max = na; else n_max = nb;   n_max = 2 * n_max;   switch (op)     {      default:	return 0;      case SLANG_POW:	for (n = 0; n < n_max; n += 2)	  {	     dcomplex_pow (c + n, to_double((VOID_STAR)a), b);	     a += da; b += db;	  }	break;      case SLANG_PLUS:	for (n = 0; n < n_max; n += 2)	  {	     c[n] = to_double((VOID_STAR)a) + b[0];	     c[n + 1] = b[1];	     a += da; b += db;	  }	break;      case SLANG_MINUS:	for (n = 0; n < n_max; n += 2)	  {	     c[n] = to_double((VOID_STAR)a) - b[0];	     c[n + 1] = -b[1];	     a += da; b += db;	  }	break;      case SLANG_TIMES:	for (n = 0; n < n_max; n += 2)	  {	     double a0 = to_double((VOID_STAR)a);	     c[n] = a0 * b[0];	     c[n + 1] = a0 * b[1];	     a += da; b += db;	  }	break;      case SLANG_DIVIDE:	       /* / */	for (n = 0; n < n_max; n += 2)	  {	     double z[2];	     if ((b[0] == 0.0) && (b[1] == 0.0))	       {		  SLang_Error = SL_DIVIDE_ERROR;		  return -1;	       }	     z[0] = to_double((VOID_STAR)a);	     z[1] = 0.0;	     SLcomplex_divide (c + n, z, b);	     a += da; b += db;	  }	break;      case SLANG_EQ: 		       /* == */	for (n = 0; n < n_max; n += 2)	  {	     ic[n/2] = ((to_double((VOID_STAR)a) == b[0]) && (0.0 == b[1]));	     a += da; b += db;	  }	break;      case SLANG_NE:		       /* != */	for (n = 0; n < n_max; n += 2)	  {	     ic[n/2] = ((to_double((VOID_STAR)a) != b[0]) || (0.0 != b[1]));	     a += da; b += db;	  }	break;     }   return 1;}static int complex_unary_result (int op, unsigned char a, unsigned char *b){   (void) a;   switch (op)     {      default:	return 0;      case SLANG_PLUSPLUS:      case SLANG_MINUSMINUS:      case SLANG_CHS:      case SLANG_MUL2:	*b = SLANG_COMPLEX_TYPE;	break;      case SLANG_SQR:		       /* |Real|^2 + |Imag|^2 ==> double */      case SLANG_ABS:		       /* |z| ==> double */	*b = SLANG_DOUBLE_TYPE;	break;      case SLANG_SIGN:	*b = SLANG_INT_TYPE;	break;     }   return 1;}static int complex_unary (int op,			  unsigned char a_type, VOID_STAR ap, unsigned int na,			  VOID_STAR bp){   unsigned int n;   double *a, *b;   int *ic;   (void) a_type;   a = (double *) ap;   b = (double *) bp;   ic = (int *) bp;   na = 2 * na;   switch (op)     {      default:	return 0;      case SLANG_PLUSPLUS:	for (n = 0; n < na; n += 2) b[n] = (a[n] + 1);	break;      case SLANG_MINUSMINUS:	for (n = 0; n < na; n += 2) b[n] = (a[n] - 1);	break;      case SLANG_CHS:	for (n = 0; n < na; n += 2)	  {	     b[n] = -(a[n]);	     b[n + 1] = -(a[n + 1]);	  }	break;      case SLANG_SQR:		       /* |Real|^2 + |Imag|^2 ==> double */	for (n = 0; n < na; n += 2)	  b[n/2] = (a[n] * a[n] + a[n + 1] * a[n + 1]);	break;      case SLANG_MUL2:	for (n = 0; n < na; n += 2)	  {	     b[n] = (2 * a[n]);	     b[n + 1] = (2 * a[n + 1]);	  }	break;      case SLANG_ABS:		       /* |z| ==> double */	for (n = 0; n < na; n += 2)	  b[n/2] = SLcomplex_abs (a + n);	break;      case SLANG_SIGN:	/* Another creative extension.  Lets return an integer which indicates	 * whether the complex number is in the upperhalf plane or not.	 */	for (n = 0; n < na; n += 2)	  {	     if (a[n + 1] < 0.0) ic[n/2] = -1;	     else if (a[n + 1] > 0.0) ic[n/2] = 1;	     else ic[n/2] = 0;	  }	break;     }   return 1;}static intcomplex_typecast (unsigned char from_type, VOID_STAR from, unsigned int num,		  unsigned char to_type, VOID_STAR to){   double *z;   double *d;   char *i;   unsigned int n;   unsigned int sizeof_i;   SLang_To_Double_Fun_Type to_double;   (void) to_type;   z = (double *) to;   switch (from_type)     {      default:	if (NULL == (to_double = SLarith_get_to_double_fun (from_type, &sizeof_i)))	  return 0;	i = (char *) from;	for (n = 0; n < num; n++)	  {	     *z++ = to_double ((VOID_STAR) i);	     *z++ = 0.0;	     i += sizeof_i;	  }	break;      case SLANG_DOUBLE_TYPE:	d = (double *) from;	for (n = 0; n < num; n++)	  {	     *z++ = d[n];	     *z++ = 0.0;	  }	break;     }   return 1;}static void complex_destroy (unsigned char type, VOID_STAR ptr){   (void) type;   SLfree ((char *)*(double **) ptr);}static int complex_push (unsigned char type, VOID_STAR ptr){   double *z;   (void) type;   z = *(double **) ptr;   return SLang_push_complex (z[0], z[1]);}static int complex_pop (unsigned char type, VOID_STAR ptr){   double *z;   (void) type;   z = *(double **) ptr;   return SLang_pop_complex (&z[0], &z[1]);}int _SLinit_slcomplex (void){   SLang_Class_Type *cl;   unsigned char *types;   if (NULL == (cl = SLclass_allocate_class ("Complex_Type")))     return -1;   (void) SLclass_set_destroy_function (cl, complex_destroy);   (void) SLclass_set_push_function (cl, complex_push);   (void) SLclass_set_pop_function (cl, complex_pop);   if (-1 == SLclass_register_class (cl, SLANG_COMPLEX_TYPE, 2 * sizeof (double),				     SLANG_CLASS_TYPE_VECTOR))     return -1;   types = _SLarith_Arith_Types;   while (*types != SLANG_DOUBLE_TYPE)     {	unsigned char t = *types++;	if ((-1 == SLclass_add_binary_op (t, SLANG_COMPLEX_TYPE, generic_complex_binary, complex_binary_result))	    || (-1 == SLclass_add_binary_op (SLANG_COMPLEX_TYPE, t, complex_generic_binary, complex_binary_result))	    || (-1 == (SLclass_add_typecast (t, SLANG_COMPLEX_TYPE, complex_typecast, 1))))	  return -1;     }   if ((-1 == (SLclass_add_binary_op (SLANG_COMPLEX_TYPE, SLANG_COMPLEX_TYPE, complex_complex_binary, complex_binary_result)))       || (-1 == (SLclass_add_binary_op (SLANG_COMPLEX_TYPE, SLANG_DOUBLE_TYPE, complex_double_binary, complex_binary_result)))       || (-1 == (SLclass_add_binary_op (SLANG_DOUBLE_TYPE, SLANG_COMPLEX_TYPE, double_complex_binary, complex_binary_result)))       || (-1 == (SLclass_add_unary_op (SLANG_COMPLEX_TYPE, complex_unary, complex_unary_result)))       || (-1 == (SLclass_add_typecast (SLANG_DOUBLE_TYPE, SLANG_COMPLEX_TYPE, complex_typecast, 1))))     return -1;   return 0;}#endif				       /* if SLANG_HAS_COMPLEX */

⌨️ 快捷键说明

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