diff options
Diffstat (limited to 'c++-libbu++/src/float.cpp')
-rw-r--r-- | c++-libbu++/src/float.cpp | 193 |
1 files changed, 100 insertions, 93 deletions
diff --git a/c++-libbu++/src/float.cpp b/c++-libbu++/src/float.cpp index c01d824..f7c2737 100644 --- a/c++-libbu++/src/float.cpp +++ b/c++-libbu++/src/float.cpp | |||
@@ -1,3 +1,10 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007-2012 Xagasoft, All rights reserved. | ||
3 | * | ||
4 | * This file is part of the libgats library and is released under the | ||
5 | * terms of the license contained in the file LICENSE. | ||
6 | */ | ||
7 | |||
1 | #include "gats/float.h" | 8 | #include "gats/float.h" |
2 | #include "gats/integer.h" | 9 | #include "gats/integer.h" |
3 | 10 | ||
@@ -7,12 +14,12 @@ | |||
7 | #include <bu/sio.h> | 14 | #include <bu/sio.h> |
8 | using namespace Bu; | 15 | using namespace Bu; |
9 | Gats::Float::Float() : | 16 | Gats::Float::Float() : |
10 | fVal( 0.0 ) | 17 | fVal( 0.0 ) |
11 | { | 18 | { |
12 | } | 19 | } |
13 | 20 | ||
14 | Gats::Float::Float( double f ) : | 21 | Gats::Float::Float( double f ) : |
15 | fVal( f ) | 22 | fVal( f ) |
16 | { | 23 | { |
17 | } | 24 | } |
18 | 25 | ||
@@ -22,109 +29,109 @@ Gats::Float::~Float() | |||
22 | 29 | ||
23 | Gats::Object *Gats::Float::clone() const | 30 | Gats::Object *Gats::Float::clone() const |
24 | { | 31 | { |
25 | return new Gats::Float( fVal ); | 32 | return new Gats::Float( fVal ); |
26 | } | 33 | } |
27 | 34 | ||
28 | void Gats::Float::write( Bu::Stream &rOut ) const | 35 | void Gats::Float::write( Bu::Stream &rOut ) const |
29 | { | 36 | { |
30 | if( fVal == 0.0 ) | 37 | if( fVal == 0.0 ) |
31 | { | 38 | { |
32 | if( signbit( fVal ) ) | 39 | if( signbit( fVal ) ) |
33 | rOut.write("FZ", 2 ); | 40 | rOut.write("FZ", 2 ); |
34 | else | 41 | else |
35 | rOut.write("Fz", 2 ); | 42 | rOut.write("Fz", 2 ); |
36 | } | 43 | } |
37 | else if( !isfinite( fVal ) ) | 44 | else if( !isfinite( fVal ) ) |
38 | { | 45 | { |
39 | if( isnan( fVal ) ) | 46 | if( isnan( fVal ) ) |
40 | { | 47 | { |
41 | if( signbit( fVal ) ) | 48 | if( signbit( fVal ) ) |
42 | rOut.write("FN", 2 ); | 49 | rOut.write("FN", 2 ); |
43 | else | 50 | else |
44 | rOut.write("Fn", 2 ); | 51 | rOut.write("Fn", 2 ); |
45 | } | 52 | } |
46 | else | 53 | else |
47 | { | 54 | { |
48 | if( signbit( fVal ) ) | 55 | if( signbit( fVal ) ) |
49 | rOut.write("FI", 2 ); | 56 | rOut.write("FI", 2 ); |
50 | else | 57 | else |
51 | rOut.write("Fi", 2 ); | 58 | rOut.write("Fi", 2 ); |
52 | } | 59 | } |
53 | } | 60 | } |
54 | else | 61 | else |
55 | { | 62 | { |
56 | rOut.write("f", 1 ); | 63 | rOut.write("f", 1 ); |
57 | double d = fVal; | 64 | double d = fVal; |
58 | bool bNeg = false; | 65 | bool bNeg = false; |
59 | int64_t iScale=0; | 66 | int64_t iScale=0; |
60 | if( signbit( d ) ) | 67 | if( signbit( d ) ) |
61 | { | 68 | { |
62 | bNeg = true; | 69 | bNeg = true; |
63 | d = -d; | 70 | d = -d; |
64 | } | 71 | } |
65 | 72 | ||
66 | iScale = log( d ) / 0x1.62e42fefa39efp+2; // log( 256.0 ) | 73 | iScale = log( d ) / 0x1.62e42fefa39efp+2; // log( 256.0 ) |
67 | if( iScale < 0 ) iScale--; | 74 | if( iScale < 0 ) iScale--; |
68 | d /= pow( 256.0, iScale ); | 75 | d /= pow( 256.0, iScale ); |
69 | 76 | ||
70 | Bu::String s; | 77 | Bu::String s; |
71 | s += (uint8_t)(d); | 78 | s += (uint8_t)(d); |
72 | d -= (int)d; | 79 | d -= (int)d; |
73 | for( int j = 0; j < 150 && d; j++ ) | 80 | for( int j = 0; j < 150 && d; j++ ) |
74 | { | 81 | { |
75 | d = d*256.0; | 82 | d = d*256.0; |
76 | s += (uint8_t)d; | 83 | s += (uint8_t)d; |
77 | d -= (int)d; | 84 | d -= (int)d; |
78 | } | 85 | } |
79 | Gats::Integer::writePackedInt( rOut, bNeg?-s.getSize():s.getSize() ); | 86 | Gats::Integer::writePackedInt( rOut, bNeg?-s.getSize():s.getSize() ); |
80 | rOut.write( s.getStr(), s.getSize() ); | 87 | rOut.write( s.getStr(), s.getSize() ); |
81 | Gats::Integer::writePackedInt( rOut, iScale ); | 88 | Gats::Integer::writePackedInt( rOut, iScale ); |
82 | } | 89 | } |
83 | } | 90 | } |
84 | 91 | ||
85 | void Gats::Float::read( Bu::Stream &rIn, char cType ) | 92 | void Gats::Float::read( Bu::Stream &rIn, char cType ) |
86 | { | 93 | { |
87 | if( cType == 'F' ) | 94 | if( cType == 'F' ) |
88 | { | 95 | { |
89 | char buf; | 96 | char buf; |
90 | rIn.read( &buf, 1 ); | 97 | rIn.read( &buf, 1 ); |
91 | switch( buf ) | 98 | switch( buf ) |
92 | { | 99 | { |
93 | case 'N': fVal = -NAN; break; | 100 | case 'N': fVal = -NAN; break; |
94 | case 'n': fVal = NAN; break; | 101 | case 'n': fVal = NAN; break; |
95 | case 'I': fVal = -INFINITY; break; | 102 | case 'I': fVal = -INFINITY; break; |
96 | case 'i': fVal = INFINITY; break; | 103 | case 'i': fVal = INFINITY; break; |
97 | case 'Z': fVal = -0.0; break; | 104 | case 'Z': fVal = -0.0; break; |
98 | case 'z': fVal = 0.0; break; | 105 | case 'z': fVal = 0.0; break; |
99 | } | 106 | } |
100 | } | 107 | } |
101 | else if( cType == 'f' ) | 108 | else if( cType == 'f' ) |
102 | { | 109 | { |
103 | int64_t iStr; | 110 | int64_t iStr; |
104 | Gats::Integer::readPackedInt( rIn, iStr ); | 111 | Gats::Integer::readPackedInt( rIn, iStr ); |
105 | bool bNeg = false; | 112 | bool bNeg = false; |
106 | if( iStr < 0 ) | 113 | if( iStr < 0 ) |
107 | { | 114 | { |
108 | bNeg = true; | 115 | bNeg = true; |
109 | iStr = -iStr; | 116 | iStr = -iStr; |
110 | } | 117 | } |
111 | Bu::String s( iStr ); | 118 | Bu::String s( iStr ); |
112 | rIn.read( s.getStr(), iStr ); | 119 | rIn.read( s.getStr(), iStr ); |
113 | fVal = 0.0; | 120 | fVal = 0.0; |
114 | for( int j = iStr-1; j > 0; j-- ) | 121 | for( int j = iStr-1; j > 0; j-- ) |
115 | { | 122 | { |
116 | fVal = (fVal+(uint8_t)s[j])*0x1p-8; | 123 | fVal = (fVal+(uint8_t)s[j])*0x1p-8; |
117 | } | 124 | } |
118 | fVal += (uint8_t)s[0]; | 125 | fVal += (uint8_t)s[0]; |
119 | int64_t iScale; | 126 | int64_t iScale; |
120 | Gats::Integer::readPackedInt( rIn, iScale ); | 127 | Gats::Integer::readPackedInt( rIn, iScale ); |
121 | fVal *= pow( 256.0, iScale ); | 128 | fVal *= pow( 256.0, iScale ); |
122 | if( bNeg ) fVal = -fVal; | 129 | if( bNeg ) fVal = -fVal; |
123 | } | 130 | } |
124 | } | 131 | } |
125 | 132 | ||
126 | Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::Float &flt ) | 133 | Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::Float &flt ) |
127 | { | 134 | { |
128 | return f << "(float) " << flt.getValue(); | 135 | return f << "(float) " << flt.getValue(); |
129 | } | 136 | } |
130 | 137 | ||