xref: /onnv-gate/usr/src/lib/libast/common/sfio/_sfputd.c (revision 12068:08a39a083754)
14887Schin /***********************************************************************
24887Schin *                                                                      *
34887Schin *               This software is part of the ast package               *
4*12068SRoger.Faulkner@Oracle.COM *          Copyright (c) 1985-2010 AT&T Intellectual Property          *
54887Schin *                      and is licensed under the                       *
64887Schin *                  Common Public License, Version 1.0                  *
78462SApril.Chin@Sun.COM *                    by AT&T Intellectual Property                     *
84887Schin *                                                                      *
94887Schin *                A copy of the License is available at                 *
104887Schin *            http://www.opensource.org/licenses/cpl1.0.txt             *
114887Schin *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
124887Schin *                                                                      *
134887Schin *              Information and Software Systems Research               *
144887Schin *                            AT&T Research                             *
154887Schin *                           Florham Park NJ                            *
164887Schin *                                                                      *
174887Schin *                 Glenn Fowler <gsf@research.att.com>                  *
184887Schin *                  David Korn <dgk@research.att.com>                   *
194887Schin *                   Phong Vo <kpv@research.att.com>                    *
204887Schin *                                                                      *
214887Schin ***********************************************************************/
224887Schin #include	"sfhdr.h"
234887Schin 
244887Schin /*	Write out a floating point value in a portable format
254887Schin **
264887Schin **	Written by Kiem-Phong Vo.
274887Schin */
284887Schin 
294887Schin #if __STD_C
_sfputd(Sfio_t * f,Sfdouble_t v)304887Schin int _sfputd(Sfio_t* f, Sfdouble_t v)
314887Schin #else
324887Schin int _sfputd(f,v)
334887Schin Sfio_t*		f;
344887Schin Sfdouble_t	v;
354887Schin #endif
364887Schin {
374887Schin #define N_ARRAY		(16*sizeof(Sfdouble_t))
384887Schin 	reg ssize_t	n, w;
394887Schin 	reg uchar	*s, *ends;
404887Schin 	int		exp;
414887Schin 	uchar		c[N_ARRAY];
424887Schin 	Sfdouble_t	x;
438462SApril.Chin@Sun.COM 	SFMTXDECL(f);
444887Schin 
458462SApril.Chin@Sun.COM 	SFMTXENTER(f,-1);
464887Schin 
474887Schin 	if(f->mode != SF_WRITE && _sfmode(f,SF_WRITE,0) < 0)
484887Schin 		SFMTXRETURN(f, -1);
494887Schin 	SFLOCK(f,0);
504887Schin 
514887Schin 	/* get the sign of v */
524887Schin 	if(v < 0.)
534887Schin 	{	v = -v;
544887Schin 		n = 1;
554887Schin 	}
564887Schin 	else	n = 0;
574887Schin 
584887Schin 	/* make the magnitude of v < 1 */
594887Schin 	if(v != 0.)
604887Schin 		v = frexpl(v,&exp);
614887Schin 	else	exp = 0;
624887Schin 
634887Schin 	/* code the sign of v and exp */
644887Schin 	if((w = exp) < 0)
654887Schin 	{	n |= 02;
664887Schin 		w = -w;
674887Schin 	}
684887Schin 
694887Schin 	/* write out the signs and the exp */
704887Schin 	SFOPEN(f,0);
714887Schin 	if(sfputc(f,n) < 0 || (w = sfputu(f,w)) < 0)
724887Schin 		SFMTXRETURN(f, -1);
734887Schin 	SFLOCK(f,0);
744887Schin 	w += 1;
754887Schin 
764887Schin 	s = (ends = &c[0])+sizeof(c);
774887Schin 	while(s > ends)
784887Schin 	{	/* get 2^SF_PRECIS precision at a time */
794887Schin 		n = (int)(x = ldexpl(v,SF_PRECIS));
804887Schin 		*--s = n|SF_MORE;
814887Schin 		v = x-n;
824887Schin 		if(v <= 0.)
834887Schin 			break;
844887Schin 	}
854887Schin 
864887Schin 	/* last byte is not SF_MORE */
874887Schin 	ends = &c[0] + sizeof(c) -1;
884887Schin 	*ends &= ~SF_MORE;
894887Schin 
904887Schin 	/* write out coded bytes */
914887Schin 	n = ends - s + 1;
924887Schin 	w = SFWRITE(f,(Void_t*)s,n) == n ? w+n : -1;
934887Schin 
944887Schin 	SFOPEN(f,0);
954887Schin 	SFMTXRETURN(f,w);
964887Schin }
97