diff options
Diffstat (limited to 'src/float.cpp')
-rw-r--r-- | src/float.cpp | 130 |
1 files changed, 118 insertions, 12 deletions
diff --git a/src/float.cpp b/src/float.cpp index 879d74b..f1e9ced 100644 --- a/src/float.cpp +++ b/src/float.cpp | |||
@@ -2,7 +2,10 @@ | |||
2 | #include "gats/integer.h" | 2 | #include "gats/integer.h" |
3 | 3 | ||
4 | #include <bu/formatter.h> | 4 | #include <bu/formatter.h> |
5 | #include <math.h> | ||
5 | 6 | ||
7 | #include <bu/sio.h> | ||
8 | using namespace Bu; | ||
6 | Gats::Float::Float() : | 9 | Gats::Float::Float() : |
7 | fVal( 0.0 ) | 10 | fVal( 0.0 ) |
8 | { | 11 | { |
@@ -19,25 +22,128 @@ Gats::Float::~Float() | |||
19 | 22 | ||
20 | void Gats::Float::write( Bu::Stream &rOut ) const | 23 | void Gats::Float::write( Bu::Stream &rOut ) const |
21 | { | 24 | { |
22 | if( sWriteCache.isEmpty() ) | 25 | if( fVal == 0.0 ) |
23 | { | 26 | { |
24 | char buf[50]; | 27 | if( signbit( fVal ) ) |
28 | rOut.write("FZ", 2 ); | ||
29 | else | ||
30 | rOut.write("Fz", 2 ); | ||
31 | } | ||
32 | else if( !isfinite( fVal ) ) | ||
33 | { | ||
34 | if( isnan( fVal ) ) | ||
35 | { | ||
36 | if( signbit( fVal ) ) | ||
37 | rOut.write("FN", 2 ); | ||
38 | else | ||
39 | rOut.write("Fn", 2 ); | ||
40 | } | ||
41 | else | ||
42 | { | ||
43 | if( signbit( fVal ) ) | ||
44 | rOut.write("FI", 2 ); | ||
45 | else | ||
46 | rOut.write("Fi", 2 ); | ||
47 | } | ||
48 | } | ||
49 | else | ||
50 | { | ||
51 | rOut.write("f", 1 ); | ||
52 | double d = fVal; | ||
53 | bool bNeg = false; | ||
54 | int64_t iScale=0; | ||
55 | if( signbit( d ) ) | ||
56 | { | ||
57 | bNeg = true; | ||
58 | d = -d; | ||
59 | } | ||
25 | 60 | ||
26 | int iSize = snprintf( buf, 50, "%la", fVal ); | 61 | if( d == 0.0 ) |
27 | sWriteCache.set( buf, iSize ); | 62 | { |
63 | } | ||
64 | else if( d < 1.0 ) | ||
65 | { | ||
66 | while( d < 1.0 ) | ||
67 | { | ||
68 | d *= 256.0; | ||
69 | iScale--; | ||
70 | } | ||
71 | } | ||
72 | else | ||
73 | { | ||
74 | while( d >= 256.0 ) | ||
75 | { | ||
76 | d *= 0x1p-8; // That's .00390625, or 1/256 | ||
77 | iScale++; | ||
78 | } | ||
79 | } | ||
80 | Bu::String s; | ||
81 | s += (uint8_t)(d); | ||
82 | d -= (int)d; | ||
83 | for( int j = 0; j < 150 && d; j++ ) | ||
84 | { | ||
85 | d = d*256.0; | ||
86 | s += (uint8_t)d; | ||
87 | d -= (int)d; | ||
88 | } | ||
89 | Gats::Integer::writePackedInt( rOut, bNeg?-s.getSize():s.getSize() ); | ||
90 | rOut.write( s.getStr(), s.getSize() ); | ||
91 | Gats::Integer::writePackedInt( rOut, iScale ); | ||
28 | } | 92 | } |
29 | rOut.write("f", 1 ); | ||
30 | Gats::Integer::writePackedInt( rOut, sWriteCache.getSize() ); | ||
31 | rOut.write( sWriteCache.getStr(), sWriteCache.getSize() ); | ||
32 | } | 93 | } |
33 | 94 | ||
34 | void Gats::Float::read( Bu::Stream &rIn, char cType ) | 95 | void Gats::Float::read( Bu::Stream &rIn, char cType ) |
35 | { | 96 | { |
36 | int iSize; | 97 | if( cType == 'F' ) |
37 | Gats::Integer::readPackedInt( rIn, iSize ); | 98 | { |
38 | char buf[50]; | 99 | char buf; |
39 | buf[rIn.read( buf, iSize )] = '\0'; | 100 | rIn.read( &buf, 1 ); |
40 | sscanf( buf, "%la", &fVal ); | 101 | switch( buf ) |
102 | { | ||
103 | case 'N': fVal = -NAN; break; | ||
104 | case 'n': fVal = NAN; break; | ||
105 | case 'I': fVal = -INFINITY; break; | ||
106 | case 'i': fVal = INFINITY; break; | ||
107 | case 'Z': fVal = -0.0; break; | ||
108 | case 'z': fVal = 0.0; break; | ||
109 | } | ||
110 | } | ||
111 | else if( cType == 'f' ) | ||
112 | { | ||
113 | int64_t iStr; | ||
114 | Gats::Integer::readPackedInt( rIn, iStr ); | ||
115 | bool bNeg = false; | ||
116 | if( iStr < 0 ) | ||
117 | { | ||
118 | bNeg = true; | ||
119 | iStr = -iStr; | ||
120 | } | ||
121 | Bu::String s( iStr ); | ||
122 | rIn.read( s.getStr(), iStr ); | ||
123 | fVal = 0.0; | ||
124 | for( int j = iStr-1; j > 0; j-- ) | ||
125 | { | ||
126 | fVal = (fVal+(uint8_t)s[j])*0x1p-8; | ||
127 | } | ||
128 | fVal += (uint8_t)s[0]; | ||
129 | int64_t iScale; | ||
130 | Gats::Integer::readPackedInt( rIn, iScale ); | ||
131 | if( iScale < 0 ) | ||
132 | { | ||
133 | for( int64_t j = 0; j > iScale; j-- ) | ||
134 | { | ||
135 | fVal *= 0x1p-8; | ||
136 | } | ||
137 | } | ||
138 | else | ||
139 | { | ||
140 | for( int64_t j = 0; j < iScale; j++ ) | ||
141 | { | ||
142 | fVal *= 256.0; | ||
143 | } | ||
144 | } | ||
145 | if( bNeg ) fVal = -fVal; | ||
146 | } | ||
41 | } | 147 | } |
42 | 148 | ||
43 | Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::Float &flt ) | 149 | Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::Float &flt ) |