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

📄 numeric.c

📁 ncbi源码
💻 C
字号:
/* * =========================================================================== * PRODUCTION $Log: numeric.c,v $ * PRODUCTION Revision 1000.0  2003/10/29 20:35:08  gouriano * PRODUCTION PRODUCTION: IMPORTED [ORIGINAL] Dev-tree R1.1 * PRODUCTION * =========================================================================== *//* FreeTDS - Library of routines accessing Sybase and Microsoft databases * Copyright (C) 1998-1999  Brian Bruns * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */#include <tds_config.h>#include <tds.h>#include <stdio.h>#ifdef DMALLOC#include <dmalloc.h>#endif/* ** these routines use arrays of unsigned char to handle arbitrary** precision numbers.  All-in-all it's probably pretty slow, but it** does work. I just heard of a GNU lib for arb. precision math, so** that might be an option in the future.*/static int multiply_byte(unsigned char *product, int num, unsigned char *multiplier);static int do_carry(unsigned char *product);static char *array_to_string(unsigned char *array, int scale, char *s);/*** The following little table is indexed by precision-1 and will** tell us the number of bytes required to store the specified** precision (with the sign).** Support precision up to 77 digits*/const int g__numeric_bytes_per_prec[] ={ -1, 2, 2, 3, 3, 4, 4, 4, 5, 5,   6, 6, 6, 7, 7, 8, 8, 9, 9, 9,  10, 10, 11, 11, 11, 12, 12, 13, 13, 14,   14, 14, 15, 15, 16, 16, 16, 17, 17, 18,   18, 19, 19, 19, 20, 20, 21, 21, 21, 22,   22, 23, 23, 24, 24, 24, 25, 25, 26, 26,   26, 27, 27, 28, 28, 28, 29, 29, 30, 30,  31, 31, 31, 32, 32, 33, 33, 33};/*** money is a special case of numeric really...that why its here*/char *tds_money_to_string(TDS_MONEY *money, char *s){unsigned char multiplier[MAXPRECISION], temp[MAXPRECISION];unsigned char product[MAXPRECISION];unsigned char *number;#ifndef WORDS_BIGENDIANunsigned char reorder[8];#endifint num_bytes = 8;int i;int pos;int neg=0;	memset(multiplier,0,MAXPRECISION);	memset(product,0,MAXPRECISION);	multiplier[0]=1;#ifdef WORDS_BIGENDIAN	/* big endian makes things easy */	number = (unsigned char *) money;#else	/* money is two 32 bit ints and thus is out of order on 	** little endian machines. Proof of the superiority of 	** big endian design. ;)	*/	number = (unsigned char *) money;	for (i=0;i<4;i++)		reorder[3-i] = number[i];	for (i=4;i<8;i++)		reorder[7-i+4] = number[i];	number = reorder;#endif	if (number[0] & 0x80) {		/* negative number -- preform two's complement */		neg = 1;		for (i=0;i<8;i++) {			number[i] = ~number[i];		}		for (i=7; i>=0; i--) {			number[i] += 1;			if (number[i]!=0) break;		}	}	for (pos=num_bytes-1;pos>=0;pos--) {		multiply_byte(product, number[pos], multiplier);		memcpy(temp, multiplier, MAXPRECISION);		memset(multiplier,0,MAXPRECISION);		multiply_byte(multiplier, 256, temp);	}	if (neg) {		s[0]='-';		array_to_string(product, 4, &s[1]);	} else {		array_to_string(product, 4, s);	}	return s;}char *tds_numeric_to_string(TDS_NUMERIC *numeric, char *s){unsigned char multiplier[MAXPRECISION], temp[MAXPRECISION];unsigned char product[MAXPRECISION];unsigned char *number;int num_bytes;int pos;	memset(multiplier,0,MAXPRECISION);	memset(product,0,MAXPRECISION);	multiplier[0]=1;	number = numeric->array;	num_bytes = g__numeric_bytes_per_prec[numeric->precision];	if (numeric->array[0] == 1)		*s++ = '-';	for (pos=num_bytes-1;pos>0;pos--) {		multiply_byte(product, number[pos], multiplier);		memcpy(temp, multiplier, MAXPRECISION);		memset(multiplier,0,MAXPRECISION);		multiply_byte(multiplier, 256, temp);	}	array_to_string(product, numeric->scale, s);	return s;}static int multiply_byte(unsigned char *product, int num, unsigned char *multiplier){unsigned char number[3];int i, top, j, start;	number[0]=num%10;	number[1]=(num/10)%10;	number[2]=(num/100)%10;	for (top=MAXPRECISION-1;top>=0 && !multiplier[top];top--);	start=0;	for (i=0;i<=top;i++) {		for (j=0;j<3;j++) {			product[j+start]+=multiplier[i]*number[j];		}		do_carry(product);		start++;	}	return 0;}static int do_carry(unsigned char *product){int j;	for (j=0;j<MAXPRECISION;j++) {		if (product[j]>9) {			product[j+1]+=product[j]/10;			product[j]=product[j]%10;		}	}	return 0;}static char *array_to_string(unsigned char *array, int scale, char *s){int top, i, j;		for (top=MAXPRECISION-1;top>=0 && top>scale && !array[top];top--);	if (top == -1)	{		s[0] = '0';		s[1] = '\0';		return s;	}	j=0;	for (i=top;i>=0;i--) {		if (top+1-j == scale) s[j++]='.';		s[j++]=array[i]+'0';	}	s[j]='\0';	return s;}

⌨️ 快捷键说明

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