Geant4-11
nf_stringToDoubles.cc
Go to the documentation of this file.
1/*
2# <<BEGIN-copyright>>
3# <<END-copyright>>
4*/
5
6#include <stdlib.h>
7#include <cmath>
8
9#include "nf_utilities.h"
10
11#ifdef WIN32
12 #include <float.h>
13 #define isfinite _finite
14#else
15 #define isfinite std::isfinite
16#endif
17
18#if defined __cplusplus
19namespace GIDI {
20using namespace GIDI;
21#endif
22
23#define numberOfStaticDoubles ( 100 * 1000 )
24
25static nfu_status nfu_stringToListOfDoubles2( char const *str, int64_t *numberConverted, double **doublePtr, char **endCharacter );
26/*
27========================================================================
28*/
29nfu_status nfu_stringToListOfDoubles( char const *str, int64_t *numberConverted, double **doublePtr, char **endCharacter ) {
30
31 *numberConverted = 0;
32 *doublePtr = NULL;
33 return( nfu_stringToListOfDoubles2( str, numberConverted, doublePtr, endCharacter ) );
34}
35/*
36========================================================================
37*/
38static nfu_status nfu_stringToListOfDoubles2( char const *str, int64_t *numberConverted, double **doublePtr, char **endCharacter ) {
39
40 int64_t i1, i2, numberConverted_initial = *numberConverted;
41 double staticDoubles[numberOfStaticDoubles];
42 nfu_status status = nfu_Okay;
43
44 for( i1 = 0; i1 < numberOfStaticDoubles; i1++, (*numberConverted)++ ) {
45 staticDoubles[i1] = strtod( str, endCharacter );
46 if( str == (char const *) *endCharacter ) {
47 if( *numberConverted > 0 ) {
48 if( ( *doublePtr = (double *) nfu_malloc( (size_t) *numberConverted * sizeof( double ) ) ) == NULL ) status = nfu_mallocError;
49 }
50 break;
51 }
52 str = (char const *) *endCharacter;
53 }
54
55 if( ( status == nfu_Okay ) && ( *doublePtr == NULL ) ) status = nfu_stringToListOfDoubles2( str, numberConverted, doublePtr, endCharacter );
56 if( *doublePtr != NULL ) {
57 double *doublePtr2 = &((*doublePtr)[numberConverted_initial]);
58
59 for( i2 = 0; i2 < i1; i2++, doublePtr2++ ) *doublePtr2 = staticDoubles[i2];
60 }
61 return( status );
62}
63/*
64============================================================
65*/
66char *nf_floatToShortestString( double value, int significantDigits, int favorEFormBy, int flags ) {
67
68 int n1, ne, nf, digitsRightOfPeriod_f, exponent;
69 char Str_e[512], Str_f[512], *Str_r = Str_e, Fmt[32], *e1, *e2;
70 const char *sign = "";
71
73
74 if( !isfinite( value ) ) {
75 sprintf( Fmt, "%%%sf", sign );
76 sprintf( Str_e, Fmt, value );
77 return( strdup( Str_e ) );
78 }
79
80 significantDigits--;
81 if( significantDigits < 0 ) significantDigits = 0;
82 if( significantDigits > 24 ) significantDigits = 24;
83
84 sprintf( Fmt, "%%%s.%de", sign, significantDigits );
85 sprintf( Str_e, Fmt, value );
86
87 e1 = strchr( Str_e, 'e' );
88 if( significantDigits == 0 ) {
89 if( *(e1 - 1) != '.' ) {
90 char *e3;
91
92 e2 = strchr( e1, 0 );
93 e3 = e2 + 1;
94 for( ; e2 != e1; e2--, e3-- ) *e3 = *e2;
95 *(e1++) = '.';
96 }
97 }
98 *e1 = 0;
99 n1 = (int) strlen( Str_e ) - 1;
100 if( flags & nf_floatToShortestString_trimZeros ) while( Str_e[n1] == '0' ) n1--; // Loop checking, 11.06.2015, T. Koi
102 if( !( flags & nf_floatToShortestString_keepPeriod ) ) if( Str_e[n1] == '.' ) n1--;
103 n1++;
104 Str_e[n1] = 0;
105
106 e1++;
107 exponent = (int) strtol( e1, &e2, 10 );
108 if( exponent != 0 ) { /* If 0, the exponent was "e+00". */
109 for( e1 = Str_e; *e1 != 0; e1++ ) ;
110 sprintf( e1, "e%d", exponent );
111
112 digitsRightOfPeriod_f = significantDigits - exponent;
113 if( ( digitsRightOfPeriod_f > 25 ) || ( exponent > 50 ) ) return( strdup( Str_r ) );
114 if( digitsRightOfPeriod_f < 0 ) digitsRightOfPeriod_f = 0;
115
116 sprintf( Fmt, "%%%s.%df", sign, digitsRightOfPeriod_f );
117 sprintf( Str_f, Fmt, value );
118
119 ne = (int) strlen( Str_e );
120 nf = (int) strlen( Str_f );
121 if( strchr( Str_f, '.' ) != NULL ) { /* '.' in string. */
122 if( flags & nf_floatToShortestString_trimZeros ) while( Str_f[nf-1] == '0' ) nf--; // Loop checking, 11.06.2015, T. Koi
123 if( Str_f[nf-1] == '.' ) {
124 if( !( flags & nf_floatToShortestString_keepPeriod ) ) nf--;
125 } }
126 else { /* Maybe we want a '.' else it looks like an integer, "12345." vs "12345". */
128 Str_f[nf] = '.';
129 nf++;
130 }
131 }
132 Str_f[nf] = 0;
133
134 if( ( nf + favorEFormBy ) < ne ) Str_r = Str_f;
135 }
136 return( strdup( Str_r ) );
137}
138
139#if defined __cplusplus
140}
141#endif
static const G4double e1[44]
static const G4double e2[44]
static const G4double e3[45]
G4int sign(const T t)
nfu_status nfu_stringToListOfDoubles(char const *str, int64_t *numberConverted, double **doublePtr, char **endCharacter)
static nfu_status nfu_stringToListOfDoubles2(char const *str, int64_t *numberConverted, double **doublePtr, char **endCharacter)
#define isfinite
#define numberOfStaticDoubles
char * nf_floatToShortestString(double value, int significantDigits, int favorEFormBy, int flags)
#define nf_floatToShortestString_includeSign
Definition: nf_utilities.h:18
@ nfu_Okay
Definition: nf_utilities.h:25
@ nfu_mallocError
Definition: nf_utilities.h:25
enum nfu_status_e nfu_status
#define nf_floatToShortestString_trimZeros
Definition: nf_utilities.h:16
void * nfu_malloc(size_t size)
#define nf_floatToShortestString_keepPeriod
Definition: nf_utilities.h:17