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