1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
#include "gats/float.h"
#include "gats/integer.h"
#include <bu/formatter.h>
#include <math.h>
#include <bu/sio.h>
using namespace Bu;
Gats::Float::Float() :
fVal( 0.0 )
{
}
Gats::Float::Float( double f ) :
fVal( f )
{
}
Gats::Float::~Float()
{
}
void Gats::Float::write( Bu::Stream &rOut ) const
{
if( fVal == 0.0 )
{
if( signbit( fVal ) )
rOut.write("FZ", 2 );
else
rOut.write("Fz", 2 );
}
else if( !isfinite( fVal ) )
{
if( isnan( fVal ) )
{
if( signbit( fVal ) )
rOut.write("FN", 2 );
else
rOut.write("Fn", 2 );
}
else
{
if( signbit( fVal ) )
rOut.write("FI", 2 );
else
rOut.write("Fi", 2 );
}
}
else
{
rOut.write("f", 1 );
double d = fVal;
bool bNeg = false;
int64_t iScale=0;
if( signbit( d ) )
{
bNeg = true;
d = -d;
}
iScale = log( d ) / 0x1.62e42fefa39efp+2; // log( 256.0 )
if( iScale < 0 ) iScale--;
d /= pow( 256.0, iScale );
Bu::String s;
s += (uint8_t)(d);
d -= (int)d;
for( int j = 0; j < 150 && d; j++ )
{
d = d*256.0;
s += (uint8_t)d;
d -= (int)d;
}
Gats::Integer::writePackedInt( rOut, bNeg?-s.getSize():s.getSize() );
rOut.write( s.getStr(), s.getSize() );
Gats::Integer::writePackedInt( rOut, iScale );
}
}
void Gats::Float::read( Bu::Stream &rIn, char cType )
{
if( cType == 'F' )
{
char buf;
rIn.read( &buf, 1 );
switch( buf )
{
case 'N': fVal = -NAN; break;
case 'n': fVal = NAN; break;
case 'I': fVal = -INFINITY; break;
case 'i': fVal = INFINITY; break;
case 'Z': fVal = -0.0; break;
case 'z': fVal = 0.0; break;
}
}
else if( cType == 'f' )
{
int64_t iStr;
Gats::Integer::readPackedInt( rIn, iStr );
bool bNeg = false;
if( iStr < 0 )
{
bNeg = true;
iStr = -iStr;
}
Bu::String s( iStr );
rIn.read( s.getStr(), iStr );
fVal = 0.0;
for( int j = iStr-1; j > 0; j-- )
{
fVal = (fVal+(uint8_t)s[j])*0x1p-8;
}
fVal += (uint8_t)s[0];
int64_t iScale;
Gats::Integer::readPackedInt( rIn, iScale );
fVal *= pow( 256.0, iScale );
if( bNeg ) fVal = -fVal;
}
}
Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::Float &flt )
{
return f << "(float) " << flt.getValue();
}
|