sync with tizen_2.0
[platform/framework/native/appfw.git] / src / base / FBaseFloat.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file                FBaseFloat.cpp
20  * @brief               This is the implementation file for Float class.
21  * @see                 Number class
22  */
23
24 // Includes
25 #include <cfloat>
26 #include <math.h>
27 #include <stdio.h>
28 #include <wchar.h>
29 #include <errno.h>
30 #include <limits.h>
31 #include <FBaseFloat.h>
32 #include <FBaseResult.h>
33 #include <FBaseSysLog.h>
34
35 namespace Tizen { namespace Base
36 {
37
38 union FloatBitRep
39 {
40         explicit
41         FloatBitRep(float f = 0.0)
42                 : value(f)
43         {
44         };
45
46         FloatBitRep(unsigned int i)
47                 : rep(i)
48         {
49         };
50
51         float value;
52         unsigned int rep;
53 };
54
55 Float::Float(float value)
56         : value(value)
57         , __pFloatImpl(null)
58 {
59 }
60
61 Float::Float(const Float& value)
62         : value(value.value)
63         , __pFloatImpl(null)
64 {
65 }
66
67 Float::~Float(void)
68 {
69 }
70
71 Float&
72 Float::operator =(const Float& rhs)
73 {
74         if (&rhs != this)
75         {
76                 value = rhs.value;
77         }
78         return *this;
79 }
80
81 int
82 Float::Compare(float f1, float f2)
83 {
84         int ret = 0;
85
86         if (f1 > f2)
87         {
88                 ret = 1;
89         }
90         else if (f1 < f2)
91         {
92                 ret = -1;
93         }
94         else
95         {
96                 ret = 0;
97         }
98
99         return ret;
100 }
101
102 int
103 Float::CompareTo(const Float& value) const
104 {
105         return(Float::Compare(this->value, value.value));
106 }
107
108 bool
109 Float::Equals(const Object& obj) const
110 {
111         const Float* pOther = dynamic_cast <const Float*>(&obj);
112
113         if (pOther == null)
114         {
115                 return false;
116         }
117
118         if (Float::Compare(this->value, (*pOther).value) == 0)
119         {
120                 return true;
121         }
122         else
123         {
124                 return false;
125         }
126 }
127
128 int
129 Float::GetHashCode(void) const
130 {
131         float* pTemp = const_cast<float*> (&value);
132         int* pValue = reinterpret_cast<int*> (pTemp);
133         return *pValue;
134 }
135
136 int
137 Float::GetHashCode(float val)
138 {
139         int* pValue = reinterpret_cast<int*> (&val);
140         return *pValue;
141 }
142
143 result
144 Float::Parse(const String& s, float& ret)
145 {
146         wchar_t* pEnd = null;
147         ret = 0;
148
149         SysTryReturn(NID_BASE, s.GetLength() >= 1, E_NUM_FORMAT, E_NUM_FORMAT,
150                 "[%s] The length of s MUST be greater than 0.", GetErrorMessage(E_NUM_FORMAT));
151
152         errno = 0;
153         ret = wcstof(s.GetPointer(), &pEnd);
154         SysTryReturn(NID_BASE, (!Float::Compare(pEnd[0], 0)), E_NUM_FORMAT, E_NUM_FORMAT,
155                 "[%s] Float parse failed. Scan stopped at (%ls).", GetErrorMessage(E_NUM_FORMAT), pEnd);
156         SysTryReturn(NID_BASE, !((!Float::Compare(ret, HUGE_VAL) || !Float::Compare(ret, -HUGE_VAL)) && (errno != 0)),
157                 E_NUM_FORMAT, E_NUM_FORMAT, "[%s] Parsed value cannot fit into a Float.", GetErrorMessage(E_NUM_FORMAT));
158
159         return E_SUCCESS;
160 }
161
162 char
163 Float::ToChar(void) const
164 {
165         return static_cast<char> (value);
166 }
167
168 short
169 Float::ToShort(void) const
170 {
171         return  static_cast<short> (value);
172 }
173
174 int
175 Float::ToInt(void) const
176 {
177         return static_cast<int> (value);
178 }
179
180 long
181 Float::ToLong(void) const
182 {
183         return static_cast<long> (value);
184 }
185
186 long long
187 Float::ToLongLong(void) const
188 {
189         return static_cast<long long> (value);
190 }
191
192 float
193 Float::ToFloat(void) const
194 {
195         return value;
196 }
197
198 double
199 Float::ToDouble(void) const
200 {
201         return static_cast<double> (value);
202 }
203
204 String
205 Float::ToString(void) const
206 {
207         return(Float::ToString(value));
208 }
209
210 String
211 Float::ToString(float value)
212 {
213         const static unsigned int MAX_DIG = 7 + 3;
214         const static unsigned int FLOAT_LENGTH_MAX = __DBL_MAX_10_EXP + MAX_DIG;
215
216         if (Float::IsNaN(value))
217         {
218                 return String(L"NaN");
219         }
220         else if (Float::IsInfinity(value))
221         {
222                 return String(L"Infinity");
223         }
224         else
225         {
226                 wchar_t sValue[FLOAT_LENGTH_MAX + 1] = {0, };
227                 swprintf(sValue, (sizeof(sValue) / sizeof(sValue[0])), L"%g", value);
228
229                 return String(sValue);
230         }
231 }
232
233 int
234 Float::ToBits(float value)
235 {
236         FloatBitRep bitRep;
237         bitRep.value = value;
238         return bitRep.rep;
239 }
240
241 float
242 Float::ToFloatFromBits(int value)
243 {
244         FloatBitRep bitRep;
245         bitRep.rep = value;
246         return bitRep.value;
247 }
248
249 bool
250 Float::IsFinite(float value)
251 {
252         return((isfinite(value) != 0) ? true : false);
253 }
254
255 bool
256 Float::IsInfinity(void) const
257 {
258         return(Float::IsInfinity(value));
259 }
260
261 bool
262 Float::IsInfinity(float value)
263 {
264         return(!Float::IsFinite(value));
265 }
266
267 bool
268 Float::IsNaN(void) const
269 {
270         return(Float::IsNaN(value));
271 }
272
273 bool
274 Float::IsNaN(float value)
275 {
276         return((isnan(value) != 0) ? true : false);
277 }
278
279 float
280 Float::GetMaxValue(void)
281 {
282         return FLT_MAX;
283 }
284
285 float
286 Float::GetMinValue(void)
287 {
288         return FLT_MIN;
289 }
290
291 }} // Tizen::Base