sync with tizen_2.0
[platform/framework/native/appfw.git] / src / base / FBaseDouble.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                FBaseDouble.cpp
20  * @brief               This is the implementation file for Double class.
21  * @see                 Number
22  */
23
24 #include <cfloat>
25 #include <math.h>
26 #include <stdio.h>
27 #include <wchar.h>
28 #include <errno.h>
29 #include <limits.h>
30 #include <FBaseDouble.h>
31 #include <FBaseResult.h>
32 #include "FBase_NativeError.h"
33 #include <FBaseSysLog.h>
34
35
36 namespace Tizen { namespace Base
37 {
38
39 union DoubleBitRep
40 {
41         explicit
42         DoubleBitRep(double d = 0.0)
43                 : value(d)
44         {
45         };
46
47         DoubleBitRep(long long l)
48                 : rep(l)
49         {
50         };
51
52         double value;
53         long long rep;
54 };
55
56 Double::Double(double value)
57         : value(value)
58         , __pDoubleImpl(null)
59 {
60 }
61
62 Double::Double(const Double& value)
63         : value(value.value)
64         , __pDoubleImpl(null)
65 {
66 }
67
68 Double::~Double(void)
69 {
70 }
71
72 Double&
73 Double::operator =(const Double& rhs)
74 {
75         if (&rhs != this)
76         {
77                 value = rhs.value;
78         }
79         return *this;
80 }
81
82 int
83 Double::Compare(double d1, double d2)
84 {
85         int ret = 0;
86         if (d1 > d2)
87         {
88                 ret = 1;
89         }
90         else if (d1 < d2)
91         {
92                 ret = -1;
93         }
94         else
95         {
96                 ret = 0;
97         }
98         return ret;
99 }
100
101 int
102 Double::CompareTo(double value) const
103 {
104         return(Double::Compare(this->value, value));
105 }
106
107 int
108 Double::CompareTo(const Double& value) const
109 {
110         return(Double::Compare(this->value, value.value));
111 }
112
113 bool
114 Double::Equals(const Object& obj) const
115 {
116         const Double* pOther = dynamic_cast <const Double*>(&obj);
117
118         if (pOther == null)
119         {
120                 return false;
121         }
122
123         if (Double::Compare(this->value, (*pOther).value) == 0)
124         {
125                 return true;
126         }
127         else
128         {
129                 return false;
130         }
131 }
132
133 int
134 Double::GetHashCode(void) const
135 {
136         double* pTemp = const_cast<double*> (&value);
137         int* pValueLow = reinterpret_cast<int*> (pTemp);
138         int* pValueHigh = pValueLow + 1;
139         return *pValueLow + *pValueHigh;
140 }
141
142 int
143 Double::GetHashCode(double val)
144 {
145         int* pValueLow = reinterpret_cast<int*> (&val);
146         int* pValueHigh = pValueLow + 1;
147         return *pValueLow + *pValueHigh;
148 }
149
150 result
151 Double::Parse(const String& s, double& ret)
152 {
153         wchar_t* pEnd = null;
154
155         errno = 0;
156         ret = wcstod(s.GetPointer(), &pEnd);
157         SysTryReturnResult(NID_BASE, ((!(!Double::Compare(ret, 0)  && errno == EINVAL)) && (pEnd[0] == 0)), E_NUM_FORMAT,
158                 "Double parse failed with reason (%s). Scan stopped at (%ls)", __ConvertNativeErrorToMessage(errno), pEnd);
159         SysTryReturnResult(NID_BASE, !(errno != 0 && (!Double::Compare(ret, HUGE_VAL)|| !Double::Compare(ret, -HUGE_VAL))),
160                 E_NUM_FORMAT, "Parsed value cannot fit into a Double.");
161
162         return E_SUCCESS;
163 }
164
165 char
166 Double::ToChar(void) const
167 {
168         return static_cast<char> (value);
169 }
170
171 short
172 Double::ToShort(void) const
173 {
174         return static_cast<short> (value);
175 }
176
177 int
178 Double::ToInt(void) const
179 {
180         return static_cast<int> (value);
181 }
182
183 long
184 Double::ToLong(void) const
185 {
186         return static_cast<long> (value);
187 }
188
189 long long
190 Double::ToLongLong(void) const
191 {
192         return static_cast<long long> (value);
193 }
194
195 float
196 Double::ToFloat(void) const
197 {
198         return static_cast<float> (value);
199 }
200
201 double
202 Double::ToDouble(void) const
203 {
204         return value;
205 }
206
207 String
208 Double::ToString(void) const
209 {
210         return(Double::ToString(value));
211 }
212
213 String
214 Double::ToString(double value)
215 {
216         const static unsigned int MAX_DIG = 17 + 3;
217         const static unsigned int DOUBLE_LENGTH_MAX = __DBL_MAX_10_EXP + MAX_DIG;
218
219         if (Double::IsNaN(value))
220         {
221                 return String(L"NaN");
222         }
223         else if (Double::IsInfinity(value))
224         {
225                 return String(L"Infinity");
226         }
227         else
228         {
229                 wchar_t sValue[DOUBLE_LENGTH_MAX + 1] = {0, };
230                 swprintf(sValue, (sizeof(sValue) / sizeof(sValue[0])), L"%#lg", value);
231                 return String(sValue);
232         }
233 }
234
235 long long
236 Double::ToBits(double value)
237 {
238         DoubleBitRep bitRep;
239         bitRep.value = value;
240         return (long long) bitRep.rep;
241 }
242
243 double
244 Double::ToDoubleFromBits(long long value)
245 {
246         DoubleBitRep bitRep;
247         bitRep.rep = value;
248         return bitRep.value;
249 }
250
251 bool
252 Double::IsFinite(double d)
253 {
254         return((isfinite(d) != 0) ? true : false);
255 }
256
257 bool
258 Double::IsInfinity(void) const
259 {
260         return(Double::IsInfinity(value));
261 }
262
263 bool
264 Double::IsInfinity(double value)
265 {
266         return(!Double::IsFinite(value));
267 }
268
269 bool
270 Double::IsNaN(void) const
271 {
272         return(Double::IsNaN(value));
273 }
274
275 bool
276 Double::IsNaN(double value)
277 {
278         return((isnan(value) != 0) ? true : false);
279 }
280
281 double
282 Double::GetMaxValue(void)
283 {
284         return DBL_MAX;
285 }
286
287 double
288 Double::GetMinValue(void)
289 {
290         return DBL_MIN;
291 }
292
293 }} // Tizen::Base