Bioplib
Protein Structure C Library
 All Data Structures Files Functions Variables Typedefs Macros Pages
ftostr.c
Go to the documentation of this file.
1 /************************************************************************/
2 /**
3 
4  \file ftostr.c
5 
6  \version V1.4
7  \date 07.07.14
8  \brief Convert a REAL to a string
9 
10  \copyright (c) UCL / Dr. Andrew C. R. Martin 1991-2014
11  EMail: andrew@bioinf.org.uk
12 
13 **************************************************************************
14 
15  This program is not in the public domain, but it may be copied
16  according to the conditions laid out in the accompanying file
17  COPYING.DOC
18 
19  The code may not be sold commercially or included as part of a
20  commercial product except as described in the file COPYING.DOC.
21 
22 **************************************************************************
23 
24  \par
25  Institute of Structural & Molecular Biology,
26  University College London,
27  Gower Street,
28  London.
29  WC1E 6BT.
30  \par
31  andrew@bioinf.org.uk
32  andrew.martin@ucl.ac.uk
33 
34 **************************************************************************
35 
36  This code is NOT IN THE PUBLIC DOMAIN, but it may be copied
37  according to the conditions laid out in the accompanying file
38  COPYING.DOC.
39 
40  The code may be modified as required, but any modifications must be
41  documented so that the person responsible can be identified.
42 
43  The code may not be sold commercially or included as part of a
44  commercial product except as described in the file COPYING.DOC.
45 
46 **************************************************************************
47 
48  Description:
49  ============
50 
51  Convert a REAL to a string
52 
53 **************************************************************************
54 
55  Usage:
56  ======
57 
58 **************************************************************************
59 
60  Revision History:
61  =================
62 - V1.0 22.11.95 Original - Routines from general.c
63 - V1.1 09.10.97 Fixed inconsistent handling of %.0f between C libs
64 - V1.2 14.11.97 Another fix to same
65 - V1.3 03.06.05 Tidied up to stop warnings under GCC 3.2.2
66 - V1.4 07.07.14 Use bl prefix for functions By: CTP
67 
68 *************************************************************************/
69 /* Doxygen
70  -------
71  #GROUP General Programming
72  #SUBGROUP String handling
73  #FUNCTION blFtostr()
74  Convert a REAL to a string using precision decimal places. If
75  precision is negative, use e-form, otherwise use f-form. This is used
76  to generate precisely formatted string versions of numbers for
77  applications where the appearance of a numeric value is important.
78 */
79 /************************************************************************/
80 /* Includes
81 */
82 #include <string.h>
83 #include <stdio.h>
84 #include <stdlib.h>
85 #include <math.h>
86 
87 #include "MathType.h"
88 #include "SysDefs.h"
89 #include "macros.h"
90 
91 /************************************************************************/
92 /* Defines and macros
93 */
94 
95 /************************************************************************/
96 /* Globals
97 */
98 
99 /************************************************************************/
100 /* Prototypes
101 */
102 
103 /************************************************************************/
104 /*>char *blFtostr(char *str, int maxlen, REAL x, int precision)
105  ------------------------------------------------------------
106 *//**
107 
108  \param[out] *str String version of number
109  \param[in] maxlen Max length for f-form. Switches to e-form
110  if exceeded
111  \param[in] x Number to convert
112  \param[in] precision Number of decimal places
113  If negative, use e-form rather than f-form
114  \return Same as str
115 
116  Convert a REAL to a string using precision decimal places. If
117  precision is negative, use e-form, otherwise use f-form. This is used
118  to generate precisely formatted string versions of numbers for
119  applications where the appearance of a numeric value is important.
120 
121 - 01.07.92 Original
122 - 07.07.92 Changed to stop value of -0.0
123 - 24.07.92 Added maxlen parameter. If the f-form will exceed this number
124  of characters we switch to e-form autmatically
125 - 28.07.92 If precision -ve, is never < maxlen-5
126 - 27.07.93 Changed to double precision I/O
127 - 09.10.97 If precision is 0 prints as an integer since C libraries
128  handle "%.0f" inconsistently
129 - 14.11.97 Oops, had forgotten to fix this in the check for e-form
130 - 03.06.05 Tidied up some loops to stop warnings under GCC 3.2.2
131 - 07.07.14 Use bl prefix for functions By: CTP
132 */
133 char *blFtostr(char *str,
134  int maxlen,
135  REAL x,
136  int precision)
137 {
138  char fmt[8],
139  *ptr;
140  int i;
141  REAL val;
142 
143  /* If usiing e-form, check whether string will fit */
144  if(precision > 0)
145  {
146  REAL lgx;
147  int len;
148 
149  lgx = log10(ABS(x)); /* Number of pre-dp places - 1 */
150  if(lgx < 0.0) lgx = 0.1; /* i.e. If x<1.0, 1 p-dp after rounding*/
151  len = (int)ceil(lgx); /* Round up to number of pre-dp places */
152  len += precision + 2; /* dp and '\0' */
153 
154  if(len > maxlen) /* String too long */
155  {
156  if(precision == 0) precision = -1; /* Set to -1 */
157  else precision *= -1; /* Switch to e-form */
158  }
159  }
160 
161  /* 09.10.97 Added check on 0 precision */
162  if((precision != 0) && (precision < -1*(maxlen-5)))
163  precision = -1*(maxlen-5);
164 
165  if(precision > 0) /* 09.10.97 Changed from >= */
166  {
167  sprintf(fmt,"%%.%dlf",precision);
168  }
169  else
170  {
171  precision = ABS(precision);
172  sprintf(fmt,"%%.%dle",precision);
173  }
174  if(precision == 0) /* Added 09.10.97 */
175  {
176  sprintf(str,"%d",(int)(x+0.5));
177  }
178  else
179  {
180  sprintf(str,fmt,x);
181  }
182 
183 
184  if(!strchr(str,'e')) /* Not e-form */
185  {
186  if(precision == 0)
187  {
188  /* Terminate string at . */
189  ptr = str;
190  while(*ptr)
191  {
192  if(*ptr++ == '.')
193  {
194  *ptr = '\0';
195  break;
196  }
197  }
198  }
199  else
200  {
201  if((ptr = strchr(str,'.'))!=NULL) /* Contains a decimal point*/
202  {
203  ptr++;
204  for(i=0; *ptr; ptr++, i++);
205  if(i<precision) /* Fewer places than precision*/
206  {
207  /* Pad with zeros */
208  for( ; i<precision; i++) *ptr++ = '0';
209  *ptr = '\0';
210  }
211  }
212  else /* No decimal point */
213  {
214  /* Move to end of string */
215  for(ptr = str; *ptr; ptr++);
216  /* Put in a dp */
217  *ptr++ = '.';
218  /* Pad with zeros */
219  for(i=0; i<precision; i++) *ptr++ = '0';
220  *ptr = '\0';
221  }
222  }
223  }
224 
225  if(str[strlen(str)-1] == '.') str[strlen(str)-1] = '\0';
226 
227  /* Strip any leading spaces */
228  /* 03.06.05 Tidied loop for gcc 3.2.2 */
229  /* 30.09.05 Fixed the warning: operation on `i' may be undefined */
230  while(str[0] == ' ')
231  {
232  i=0;
233  while(i<strlen(str))
234  {
235  str[i] = str[i+1];
236  i++;
237  }
238  }
239 
240 
241  /* Remove any leading minus sign if value is 0.0 */
242  sscanf(str,"%lf",&val);
243  if(val == 0.0 && str[0] == '-')
244  {
245  /* 03.06.05 Tidied loop for gcc 3.2.2 */
246  /* 30.09.05 Fixed the warning: operation on `i' may be undefined */
247  i=0;
248  while(i<strlen(str))
249  {
250  str[i] = str[i+1];
251  i++;
252  }
253  }
254 
255  return(str);
256 }
257 
#define NULL
Definition: array2.c:99
char * blFtostr(char *str, int maxlen, REAL x, int precision)
Definition: ftostr.c:133
Useful macros.
double REAL
Definition: MathType.h:67
System-type variable type definitions.
#define ABS(x)
Definition: macros.h:235
Type definitions for maths.