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

📄 io.c

📁 生成直角Steiner树的程序包
💻 C
📖 第 1 页 / 共 2 页
字号:
double		mantissa,	/* IN - scaled mantissa value */int		expon,		/* IN - exponent (power of 10) */int		nsig		/* IN - num significant mantissa digits */){struct numlist *	p;	p = NEW (struct numlist);	p -> mantissa	= mantissa;	p -> expon	= expon;	p -> nsig	= (nsig > 0) ? nsig : 1;	p -> next	= NULL;	return (p);}/* * Compute a common scale value for all of the numbers in the given list. * In most cases, we can obtain an "optimum" scale value -- wherein every * number in the list will have an integer value that can be represented * exactly.  In cases where there are many significant digits, or a wide * span of exponent values, we must compromise. */	intcompute_scaling_factor (struct numlist *	p	/* IN - list of numbers to scale */){int		k;int		min_expon;int		max_expon;	for (;;) {		if (p EQ NULL) {			/* No non-zero numbers -- don't scale at all! */			return (0);		}		if (p -> mantissa NE 0.0) break;		p = p -> next;	}	min_expon = p -> expon;	max_expon = p -> expon + p -> nsig;	for (p = p -> next; p NE NULL; p = p -> next) {		if (p -> mantissa EQ 0) continue;		if (p -> expon < min_expon) {			min_expon = p -> expon;		}		k = p -> expon + p -> nsig;		if (k > max_expon) {			max_expon = k;		}	}	/* Let D be a significant digit from the list, E be its		*/	/* exponent so that the digit has value D * 10**E.  We now know	*/	/* the smallest and largest of the E values.  If the spread is	*/	/* MAX_INT_DIGITS or fewer, we win!  (Use the smallest E.)	*/	/* Otherwise, try to split the difference.			*/	max_expon -= MAX_INT_DIGITS;	if (max_expon > min_expon) {		/* Must compromise. */		min_expon = (max_expon + min_expon + 1) / 2;	}	/* Our internal representation is such that dividing it by	*/	/* 10**-min_expon yields external values.  (Note that min_expon	*/	/* is typically negative here, in which case we would really be	*/	/* multiplying by 10**(-min_expon).)				*/	return (-min_expon);}/* * Set the scaling info properly for the given scale factor. */	voidset_scale_info (struct scale_info *	sip,		/* OUT - scale_info to initialize */int			scale_factor	/* IN - scale factor to establish */){int		i;double		pow10;double		p;	memset (sip, 0, sizeof (*sip));	sip -> scale	= scale_factor;	i = scale_factor;	if (i < 0) {		i = - i;	}	/* Compute p = 10 ** i. */	pow10 = 1.0;	p = 10.0;	while (i > 0) {		if ((i & 1) NE 0) {			pow10 *= p;		}		p *= p;		i >>= 1;	}	if (scale_factor < 0) {		sip -> scale_mul = pow10;		sip -> scale_div = 1.0;	}	else {		sip -> scale_mul = 1.0;		sip -> scale_div = pow10;	}}/* * This routine converts the coordinate in the given numlist structure * to an internal coordinate value, scaled as specified by the scaling_factor * parameter.  The given numlist structure is freed. */	coord_tread_numlist (struct numlist *	nlp,		/* IN - string list structure */struct scale_info *	sip		/* IN - problem scaling info */){int		i;int		target_expon;int		expon;coord_t		value;double		pow10;double		p;	target_expon = - sip -> scale;	value = nlp -> mantissa;	expon = nlp -> expon;	i = expon - target_expon;	if (i < 0) {		i = - i;	}	pow10 = 1.0;	p = 10.0;	while (i > 0) {		if ((i & 1) NE 0) {			pow10 *= p;		}		p *= p;		i >>= 1;	}	if (expon > target_expon) {		value *= pow10;	}	else if (expon < target_expon) {		value /= pow10;	}	free ((char *) nlp);	return (value);}/* * This routine gets the next character from stdin.  For the case of * interactive input, it makes sure that an EOF condition is * "permanent" -- that is, getc will not be called again after it * indicates EOF. */	static	intnext_char (FILE *		fp		/* IN - input stream to read from */){int		c;	if (feof (fp)) {		/* Don't do "getc" again -- EOF is permanent! */		return (EOF);	}	c = getc (fp);	return (c);}/* * This routine converts the given internal-form coordinate to a * printable ASCII string in external form.  The internal form is an * integer (to eliminate numeric problems), but the external data * may actually involve decimal fractions.  This routine therefore * properly scales the coordinate during conversion to printable form. */	voidcoord_to_string (char *			buf,	/* OUT - buffer to put ASCII text into */coord_t			coord,	/* IN - coordinate to convert */struct scale_info *	sip	/* IN - problem scaling info */){	/* Just pretend its a distance -- distances certainly	*/	/* do not have LESS precision than coordinates...	*/	dist_to_string (buf, coord, sip);}/* * This routine converts the given internal-form distance to a * printable ASCII string in external form.  The internal form is an * integer (to eliminate numeric problems), but the external data * may actually involve decimal fractions.  This routine therefore * properly scales the distance during conversion to printable form. */	voiddist_to_string (char *			buf,	/* OUT - buffer to put ASCII text into */dist_t			dist,	/* IN - distance to convert */struct scale_info *	sip	/* IN - problem scaling info */){int		i;int		digit;int		mindig;double		ipart;double		fpart;double		div10;char *		p;char *		endp;char		tmp [256];	if (dist < 0.0) {		dist = -dist;		*buf++ = '-';	}	if (dist EQ 0) {		*buf++ = '0';		*buf++ = '\0';		return;	}	mindig = sip -> min_precision;	memset (tmp, '0', sizeof (tmp));	p = &tmp [128];	endp = p;	ipart = floor (dist);	while (ipart > 0) {		div10 = floor (ipart / 10.0);		digit = ipart - floor (10.0 * div10 + 0.5);		*--p = digit + '0';		ipart = div10;	}	if ((sip -> scale <= 0) AND (mindig EQ 0)) {		/* The coordinates and edge costs are all integers	*/		/* (both internally and externally so scaling is a	*/		/* "no-op").  The metric is not Euclidean, so nothing	*/		/* irrational appears.  Always output integers, and do	*/		/* NOT insert a decimal point...			*/		endp [-(sip -> scale)] = '\0';		strcpy (buf, p);		return;	}	if (sip -> scale >= 0) {		if (p + sip -> scale > endp) {			p = endp - sip -> scale;		}		for (i = 0; i <= sip -> scale; i++) {			endp [1 - i] = endp [0 - i];		}		endp [1 - i] = '.';		++endp;		fpart = dist - floor (dist);		while ((endp - p) < (mindig + 1)) {			fpart *= 10.0;			digit = (int) floor (fpart);			*endp++ = digit + '0';			fpart -= ((double) digit);		}	}	else if (mindig EQ 0) {		endp -= sip -> scale;	}	else {		fpart = dist - floor (dist);		for (i = sip -> scale; i < 0; i++) {			fpart *= 10.0;			digit = (int) floor (fpart);			*endp++ = digit + '0';			fpart -= ((double) digit);			--mindig;		}		if (mindig > 0) {			*endp++ = '.';			while (mindig > 0) {				fpart *= 10.0;				digit = (int) floor (fpart);				*endp++ = digit + '0';				fpart -= ((double) digit);				--mindig;			}		}	}	*endp = '\0';	strcpy (buf, p);}/* * This routine sets up the various parameters needed for outputting * scaled coordinates.  We want to print coordinates/distances with * the minimum fixed precision whenever this gives the exact result. * Otherwise we will print the coordinates/distances with full * precision. * * The minimum fixed precision is exact ONLY when ALL of the following * are true: * *	- The metric must not be EUCLIDEAN, since distances become *	  irrational even if the coordinates are finite precision. *	  Coordinates of Euclidean Steiner points are also irrational. * *	- The SCALED vertex coordinates must all be integral. * *	- The SCALED hyperedge costs must all be integral. * * Note: we actually check the scaled data for integrality because there * are some old FST generators that do not implement scaling!  Such * data always contain a scale factor of zero and non-integral coordinates * and distances. */	voidinit_output_conversion (struct pset *		pts,		/* IN - list of terminals */int			metric,		/* IN - the metric */struct scale_info *	sip		/* IN/OUT - problem scaling info */){int			i;struct point *		p;bool			integral;double			c;	integral = TRUE;	if (pts NE NULL) {		p = &(pts -> a [0]);		for (i = 0; i < pts -> n; i++, p++) {			c = floor ((double) (p -> x));			if (c NE p -> x) {				integral = FALSE;				break;			}			c = floor ((double) (p -> y));			if (c NE p -> y) {				integral = FALSE;				break;			}		}	}	if (integral AND (metric NE EUCLIDEAN)) {		sip -> min_precision = 0;	}	else {		sip -> min_precision = DBL_DIG + 1;	}}

⌨️ 快捷键说明

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