aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/float.cpp130
-rw-r--r--src/object.cpp3
-rw-r--r--src/unit/basic.unit2
-rw-r--r--src/unit/float.unit75
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>
8using namespace Bu;
6Gats::Float::Float() : 9Gats::Float::Float() :
7 fVal( 0.0 ) 10 fVal( 0.0 )
8{ 11{
@@ -19,25 +22,128 @@ Gats::Float::~Float()
19 22
20void Gats::Float::write( Bu::Stream &rOut ) const 23void 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
34void Gats::Float::read( Bu::Stream &rIn, char cType ) 95void 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
43Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::Float &flt ) 149Bu::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
20using namespace Bu;
21
22suite 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}