diff options
Diffstat (limited to '')
| -rw-r--r-- | src/float.cpp | 130 | ||||
| -rw-r--r-- | src/object.cpp | 3 | ||||
| -rw-r--r-- | src/unit/basic.unit | 2 | ||||
| -rw-r--r-- | src/unit/float.unit | 75 |
4 files changed, 196 insertions, 14 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 ) |
diff --git a/src/object.cpp b/src/object.cpp index 1908904..af81017 100644 --- a/src/object.cpp +++ b/src/object.cpp | |||
| @@ -46,7 +46,8 @@ Gats::Object *Gats::Object::read( Bu::Stream &rIn ) | |||
| 46 | pObj = new Gats::Dictionary(); | 46 | pObj = new Gats::Dictionary(); |
| 47 | break; | 47 | break; |
| 48 | 48 | ||
| 49 | case 'f': | 49 | case 'f': // Normal floats |
| 50 | case 'F': // Special float values | ||
| 50 | pObj = new Gats::Float(); | 51 | pObj = new Gats::Float(); |
| 51 | break; | 52 | break; |
| 52 | 53 | ||
diff --git a/src/unit/basic.unit b/src/unit/basic.unit index 369e095..3ab8dc2 100644 --- a/src/unit/basic.unit +++ b/src/unit/basic.unit | |||
| @@ -145,7 +145,7 @@ suite Basic | |||
| 145 | 145 | ||
| 146 | { | 146 | { |
| 147 | Gats::Dictionary dict; | 147 | Gats::Dictionary dict; |
| 148 | dict.insert("bool", true ); | 148 | dict.insert("bool", new Gats::Boolean(true) ); |
| 149 | dict.insert("int", 33403055 ); | 149 | dict.insert("int", 33403055 ); |
| 150 | dict.insert("str", "Hey there" ); | 150 | dict.insert("str", "Hey there" ); |
| 151 | dict.write( mb ); | 151 | dict.write( mb ); |
diff --git a/src/unit/float.unit b/src/unit/float.unit new file mode 100644 index 0000000..0473ffb --- /dev/null +++ b/src/unit/float.unit | |||
| @@ -0,0 +1,75 @@ | |||
| 1 | // vim: syntax=cpp | ||
| 2 | /* | ||
| 3 | * Copyright (C) 2007-2010 Xagasoft, All rights reserved. | ||
| 4 | * | ||
| 5 | * This file is part of the libbu++ library and is released under the | ||
| 6 | * terms of the license contained in the file LICENSE. | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include "gats/dictionary.h" | ||
| 10 | #include "gats/float.h" | ||
| 11 | #include "gats/string.h" | ||
| 12 | |||
| 13 | #include "bu/membuf.h" | ||
| 14 | #include "bu/list.h" | ||
| 15 | #include "bu/sio.h" | ||
| 16 | |||
| 17 | #include <stdlib.h> | ||
| 18 | #include <math.h> | ||
| 19 | |||
| 20 | using namespace Bu; | ||
| 21 | |||
| 22 | suite Basic | ||
| 23 | { | ||
| 24 | void rw( double dVal ) | ||
| 25 | { | ||
| 26 | Bu::MemBuf mb; | ||
| 27 | |||
| 28 | Gats::Float( dVal ).write( mb ); | ||
| 29 | |||
| 30 | mb.setPos( 0 ); | ||
| 31 | |||
| 32 | Gats::Object *pObj = Gats::Object::read( mb ); | ||
| 33 | unitTest( pObj != NULL ); | ||
| 34 | unitTest( pObj->getType() == Gats::typeFloat ); | ||
| 35 | Gats::Float *pFlt = dynamic_cast<Gats::Float *>(pObj); | ||
| 36 | // printf("In: %a\nOut: %a\n", dVal, pFlt->getValue() ); | ||
| 37 | if( isnan( dVal ) ) | ||
| 38 | unitTest( isnan(pFlt->getValue()) == isnan(dVal) ); | ||
| 39 | else | ||
| 40 | unitTest( pFlt->getValue() == dVal ); | ||
| 41 | unitTest( signbit(pFlt->getValue()) == signbit(dVal) ); | ||
| 42 | |||
| 43 | delete pObj; | ||
| 44 | } | ||
| 45 | |||
| 46 | test positive | ||
| 47 | { | ||
| 48 | rw( 8485738457.0 ); | ||
| 49 | rw( 0.000000000000001928173 ); | ||
| 50 | rw( 1.0 ); | ||
| 51 | rw( 0.0 ); | ||
| 52 | rw( M_PI ); | ||
| 53 | } | ||
| 54 | |||
| 55 | test negitave | ||
| 56 | { | ||
| 57 | rw( -8485738457.0 ); | ||
| 58 | rw( -0.000000000000001928173 ); | ||
| 59 | rw( -1.0 ); | ||
| 60 | rw( -0.0 ); | ||
| 61 | rw( -M_PI ); | ||
| 62 | } | ||
| 63 | |||
| 64 | test inf | ||
| 65 | { | ||
| 66 | rw( INFINITY ); | ||
| 67 | rw( -INFINITY ); | ||
| 68 | } | ||
| 69 | |||
| 70 | test nan | ||
| 71 | { | ||
| 72 | rw( NAN ); | ||
| 73 | rw( -NAN ); | ||
| 74 | } | ||
| 75 | } | ||
