StRoot  1
StMath.cc
1 /***************************************************************************
2  *
3  * \$Id: StMath.cc,v 1.3 2004/01/27 02:51:35 perev Exp \$
4  *
5  * Author: Victor Perev - Created: 19 Nov 2003
6  *
7  ***************************************************************************
8  *
9  * Description:
10  * Set of math utilities as a static members of StMath class
11  *
12  ***************************************************************************
13  *
14  * \$Log: StMath.cc,v \$
15  * Revision 1.3 2004/01/27 02:51:35 perev
16  * Add finite() for float
17  *
18  * Revision 1.2 2003/11/25 04:21:54 perev
19  * finite(float) implemented
20  *
21  * Revision 1.1 2003/11/20 03:02:07 perev
22  * New utility class StMath
23  *
24  *
25  **************************************************************************/
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <math.h>
29 #include "StMath.hh"
30 //_____________________________________________________________________________
31 int StMath::Finite(const double &f)
32 {return ::finite(f);}
33
34 //_____________________________________________________________________________
35 int StMath::Finite(const float &f)
36 {
37 /*
38 The IEEE single precision floating point standard representation requires a 32 bit word, which may be represented as numbered from 0 to 31, left to right. The first bit is the sign bit, S, the next eight bits are the exponent bits, 'E', and the final 23 bits are the fraction 'F':
39
40  S EEEEEEEE FFFFFFFFFFFFFFFFFFFFFFF
41  0 1 8 9 31
42
43 The value V represented by the word may be determined as follows:
44
45
46 If E=255 and F is nonzero, then V=NaN ("Not a number")
47 If E=255 and F is zero and S is 1, then V=-Infinity
48 If E=255 and F is zero and S is 0, then V=Infinity
49 If 0<E<255 then V=(-1)**S * 2 ** (E-127) * (1.F) where "1.F" is intended to represent the binary number created by prefixing F with an implicit leading 1 and a binary point.
50 If E=0 and F is nonzero, then V=(-1)**S * 2 ** (-126) * (0.F) These are "unnormalized" values.
51 If E=0 and F is zero and S is 1, then V=-0
52 If E=0 and F is zero and S is 0, then V=0
53 */
54  unsigned int w,F,S,E;
55  w = *((int*)&f);
56  if (w==0) return 1;
57  E = (w<<1)>>24;
58  if (E!=255 && E!=0) return 1;
59  F = (w<<9)>>9;
60  S = (w>>31);
61
62  if(E==255 && F!=0 ) return 0; // NaN
63  if(E==255 && F==0 && S==1) return 0; //-infinity
64  if(E==255 && F==0 && S==0) return 0; //+infinity
65  if(E== 0 && F==0 && S==1) return 0; //-0
66  return 1;
67 }
68
69
70 //_____________________________________________________________________________
71 int StMath::tooBig(float *arr, int narr, double toobig)
72 {
73  for (int i=0;i<narr;i++) {
74  if (! Finite(arr[i]) ) return 1;
75  if ( ::fabs (arr[i]) > toobig) return 2;
76  }
77  return 0;
78 }
79 //_____________________________________________________________________________
80 int StMath::tooBig(double *arr, int narr, double toobig)
81 {
82  for (int i=0;i<narr;i++) {
83  if (!::finite(arr[i]) ) return 1;
84  if ( ::fabs (arr[i]) > toobig) return 2;
85  }
86  return 0;
87 }
88
89
90
91