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