1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1985-2007 AT&T Knowledge Ventures * 5 * and is licensed under the * 6 * Common Public License, Version 1.0 * 7 * by AT&T Knowledge Ventures * 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 44 SFMTXSTART(f,-1); 45 46 if(f->mode != SF_WRITE && _sfmode(f,SF_WRITE,0) < 0) 47 SFMTXRETURN(f, -1); 48 SFLOCK(f,0); 49 50 /* get the sign of v */ 51 if(v < 0.) 52 { v = -v; 53 n = 1; 54 } 55 else n = 0; 56 57 /* make the magnitude of v < 1 */ 58 if(v != 0.) 59 v = frexpl(v,&exp); 60 else exp = 0; 61 62 /* code the sign of v and exp */ 63 if((w = exp) < 0) 64 { n |= 02; 65 w = -w; 66 } 67 68 /* write out the signs and the exp */ 69 SFOPEN(f,0); 70 if(sfputc(f,n) < 0 || (w = sfputu(f,w)) < 0) 71 SFMTXRETURN(f, -1); 72 SFLOCK(f,0); 73 w += 1; 74 75 s = (ends = &c[0])+sizeof(c); 76 while(s > ends) 77 { /* get 2^SF_PRECIS precision at a time */ 78 n = (int)(x = ldexpl(v,SF_PRECIS)); 79 *--s = n|SF_MORE; 80 v = x-n; 81 if(v <= 0.) 82 break; 83 } 84 85 /* last byte is not SF_MORE */ 86 ends = &c[0] + sizeof(c) -1; 87 *ends &= ~SF_MORE; 88 89 /* write out coded bytes */ 90 n = ends - s + 1; 91 w = SFWRITE(f,(Void_t*)s,n) == n ? w+n : -1; 92 93 SFOPEN(f,0); 94 SFMTXRETURN(f,w); 95 } 96