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 ) |
