1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1985-2009 AT&T Intellectual Property * 5 * and is licensed under the * 6 * Common Public License, Version 1.0 * 7 * by AT&T Intellectual Property * 8 * * 9 * A copy of the License is available at * 10 * http://www.opensource.org/licenses/cpl1.0.txt * 11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 12 * * 13 * Information and Software Systems Research * 14 * AT&T Research * 15 * Florham Park NJ * 16 * * 17 * Glenn Fowler <gsf@research.att.com> * 18 * David Korn <dgk@research.att.com> * 19 * Phong Vo <kpv@research.att.com> * 20 * * 21 ***********************************************************************/ 22 #include "sfhdr.h" 23 24 /* Write out a floating point value in a portable format 25 ** 26 ** Written by Kiem-Phong Vo. 27 */ 28 29 #if __STD_C 30 int _sfputd(Sfio_t* f, Sfdouble_t v) 31 #else 32 int _sfputd(f,v) 33 Sfio_t* f; 34 Sfdouble_t v; 35 #endif 36 { 37 #define N_ARRAY (16*sizeof(Sfdouble_t)) 38 reg ssize_t n, w; 39 reg uchar *s, *ends; 40 int exp; 41 uchar c[N_ARRAY]; 42 Sfdouble_t x; 43 SFMTXDECL(f); 44 45 SFMTXENTER(f,-1); 46 47 if(f->mode != SF_WRITE && _sfmode(f,SF_WRITE,0) < 0) 48 SFMTXRETURN(f, -1); 49 SFLOCK(f,0); 50 51 /* get the sign of v */ 52 if(v < 0.) 53 { v = -v; 54 n = 1; 55 } 56 else n = 0; 57 58 /* make the magnitude of v < 1 */ 59 if(v != 0.) 60 v = frexpl(v,&exp); 61 else exp = 0; 62 63 /* code the sign of v and exp */ 64 if((w = exp) < 0) 65 { n |= 02; 66 w = -w; 67 } 68 69 /* write out the signs and the exp */ 70 SFOPEN(f,0); 71 if(sfputc(f,n) < 0 || (w = sfputu(f,w)) < 0) 72 SFMTXRETURN(f, -1); 73 SFLOCK(f,0); 74 w += 1; 75 76 s = (ends = &c[0])+sizeof(c); 77 while(s > ends) 78 { /* get 2^SF_PRECIS precision at a time */ 79 n = (int)(x = ldexpl(v,SF_PRECIS)); 80 *--s = n|SF_MORE; 81 v = x-n; 82 if(v <= 0.) 83 break; 84 } 85 86 /* last byte is not SF_MORE */ 87 ends = &c[0] + sizeof(c) -1; 88 *ends &= ~SF_MORE; 89 90 /* write out coded bytes */ 91 n = ends - s + 1; 92 w = SFWRITE(f,(Void_t*)s,n) == n ? w+n : -1; 93 94 SFOPEN(f,0); 95 SFMTXRETURN(f,w); 96 } 97