All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ttmathdec.h
Go to the documentation of this file.
1 /*
2  * This file is a part of TTMath Bignum Library
3  * and is distributed under the (new) BSD licence.
4  * Author: Tomasz Sowa <t.sowa@ttmath.org>
5  */
6 
7 /*
8  * Copyright (c) 2012, Tomasz Sowa
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions are met:
13  *
14  * * Redistributions of source code must retain the above copyright notice,
15  * this list of conditions and the following disclaimer.
16  *
17  * * Redistributions in binary form must reproduce the above copyright
18  * notice, this list of conditions and the following disclaimer in the
19  * documentation and/or other materials provided with the distribution.
20  *
21  * * Neither the name Tomasz Sowa nor the names of contributors to this
22  * project may be used to endorse or promote products derived
23  * from this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
29  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
35  * THE POSSIBILITY OF SUCH DAMAGE.
36  */
37 
38 #ifndef headerfilettmathdec
39 #define headerfilettmathdec
40 
41 #include "ttmathtypes.h"
42 #include "ttmaththreads.h"
43 #include "ttmathuint.h"
44 
45 
46 
47 namespace ttmath
48 {
49 
50 template<uint value_size, uint dec_digits>
51 class Dec
52 {
53 public:
54 
56  unsigned char info;
57 
58 
64  #define TTMATH_DEC_SIGN 128
65 
66 
71  #define TTMATH_DEC_NAN 64
72 
73 
74 
75 
76  Dec()
77  {
79  }
80 
81 
82  Dec(const char * s)
83  {
85  FromString(s);
86  }
87 
88 
90  {
91  FromString(s);
92 
93  return *this;
94  }
95 
96 
97  uint FromString(const char * s, const char ** after_source = 0, bool * value_read = 0)
98  {
99  return FromStringBase(s, after_source, value_read);
100  }
101 
102 
103  void ToString(std::string & result) const
104  {
105  ToStringBase(result);
106  }
107 
108 
114  void ClearInfoBit(unsigned char bit)
115  {
116  info = info & (~bit);
117  }
118 
119 
126  void SetInfoBit(unsigned char bit)
127  {
128  info = info | bit;
129  }
130 
131 
137  bool IsInfoBit(unsigned char bit) const
138  {
139  return (info & bit) != 0;
140  }
141 
142 
143  bool IsNan() const
144  {
145  return IsInfoBit(TTMATH_DEC_NAN);
146  }
147 
148 
149  bool IsSign() const
150  {
151  return IsInfoBit(TTMATH_DEC_SIGN);
152  }
153 
154 
165  void SetSign()
166  {
168  }
169 
170 
171  void SetNaN()
172  {
174  }
175 
176 
177  void Abs()
178  {
180  }
181 
182 
183 
185  {
186  uint c = 0;
187 
188  if( IsSign() == arg.IsSign() )
189  {
190  c += value.Add(arg.value);
191  }
192  else
193  {
194  bool is_sign;
195 
196  if( value > arg.value )
197  {
198  is_sign = IsSign();
199  value.Sub(arg.value);
200  }
201  else
202  {
203  is_sign = arg.IsSign();
204  UInt<value_size> temp(this->value);
205  value = arg.value;
206  value.Sub(temp);
207  }
208 
209  is_sign ? SetSign() : Abs();
210  }
211 
212  if( c )
213  SetNaN();
214 
215  return (c==0)? 0 : 1;
216  }
217 
218 /*
219  uint Sub(const Dec<value_size, dec_digits> & arg)
220  {
221  }
222 */
223 
224 private:
225 
226 
227 
228 
229 
230 
231 #ifndef TTMATH_MULTITHREADS
232 
235  void SetMultipler(UInt<value_size> & result)
236  {
237  // this guardian is initialized before the program runs (static POD type)
238  static int guardian = 0;
239  static UInt<value_size> multipler;
240 
241  if( guardian == 0 )
242  {
243  multipler = 10;
244  multipler.Pow(dec_digits);
245  guardian = 1;
246  }
247 
248  result = multipler;
249  }
250 
251 #else
252 
255  void SetMultipler(UInt<value_size> & result)
256  {
257  // this guardian is initialized before the program runs (static POD type)
258  volatile static sig_atomic_t guardian = 0;
259  static UInt<value_size> * pmultipler;
260 
261  // double-checked locking
262  if( guardian == 0 )
263  {
264  ThreadLock thread_lock;
265 
266  // locking
267  if( thread_lock.Lock() )
268  {
269  static UInt<value_size> multipler;
270 
271  if( guardian == 0 )
272  {
273  pmultipler = &multipler;
274  multipler = 10;
275  multipler.Pow(dec_digits);
276  guardian = 1;
277  }
278  }
279  else
280  {
281  // there was a problem with locking, we store the result directly in 'result' object
282  result = 10;
283  result.Pow(dec_digits);
284 
285  return;
286  }
287 
288  // automatically unlocking
289  }
290 
291  result = *pmultipler;
292  }
293 
294 #endif
295 
296 
297 
301  template<class char_type>
302  uint FromStringBase(const char_type * s, const char_type ** after_source = 0, bool * value_read = 0)
303  {
304  UInt<value_size> multipler;
305  const char_type * after;
306  uint c = 0;
307  info = 0;
308 
310 
311  if( *s == '-' )
312  {
313  s += 1;
314  SetSign();
315  }
316  else
317  if( *s == '+' )
318  {
319  s += 1;
320  }
321 
322  c += value.FromString(s, 10, &after, value_read);
323 
324  if( after_source )
325  *after_source = after;
326 
327  SetMultipler(multipler);
328  c += value.Mul(multipler);
329 
330  if( *after == '.' )
331  c += FromStringBaseAfterComma(after+1, after_source);
332 
333  if( c )
335 
336  return (c==0)? 0 : 1;
337  }
338 
339 
340  template<class char_type>
341  uint FromStringBaseAfterComma(const char_type * s, const char_type ** after_source = 0, bool * value_read = 0)
342  {
343  UInt<value_size> temp;
344  UInt<value_size> multipler;
345  sint z;
346  uint c = 0;
347  size_t i = dec_digits;
348 
349  SetMultipler(multipler);
350 
351  for( ; i>0 && (z=Misc::CharToDigit(*s, 10)) != -1 ; --i, ++s )
352  {
353  multipler.DivInt(10);
354  temp.SetZero();
355 
356  if( value_read )
357  *value_read = true;
358 
359  if( c == 0 )
360  {
361  temp.table[0] = z;
362  c += temp.Mul(multipler);
363  c += value.Add(temp);
364  }
365  }
366 
367  if( i == 0 && (z=Misc::CharToDigit(*s, 10)) != -1 && z >= 5 )
368  c += value.AddOne();
369 
370  if( after_source )
371  {
372  while( (z=Misc::CharToDigit(*s, 10)) != -1 )
373  s += 1;
374 
375  *after_source = s;
376  }
377 
378  return c;
379  }
380 
381 
382 
383  template<class string_type>
384  void ToStringBase(string_type & result) const
385  {
386  if( IsNan() )
387  {
388  result = "NaN";
389  return;
390  }
391 
392  value.ToStringBase(result, 10, IsSign());
393 
394  if( dec_digits > 0 )
395  {
396  size_t size = result.size();
397 
398  if( IsSign() && size > 0 )
399  size -= 1;
400 
401  if( dec_digits >= size )
402  {
403  size_t zeroes = dec_digits - size + 1;
404  size_t start = IsSign() ? 1 : 0;
405  result.insert(start, zeroes, '0');
406  }
407 
408  result.insert(result.end() - dec_digits, '.');
409  }
410  }
411 
412 
413 
414 };
415 
416 
417 } // namespace
418 
419 #endif
bool IsNan() const
Definition: ttmathdec.h:143
bool IsInfoBit(unsigned char bit) const
Definition: ttmathdec.h:137
static void SkipWhiteCharacters(const char_type *&c)
Definition: ttmathmisc.h:160
uint Add(const Dec< value_size, dec_digits > &arg)
Definition: ttmathdec.h:184
static uint CharToDigit(uint c)
Definition: ttmathmisc.h:181
Dec()
Definition: ttmathdec.h:76
void SetNaN()
Definition: ttmathdec.h:171
void ToString(std::string &result) const
Definition: ttmathdec.h:103
template class UInt<uint>
void SetInfoBit(unsigned char bit)
Definition: ttmathdec.h:126
UInt< value_size > value
Definition: ttmathdec.h:55
uint FromString(const char *s, const char **after_source=0, bool *value_read=0)
Definition: ttmathdec.h:97
bool IsSign() const
Definition: ttmathdec.h:149
signed int sint
Definition: ttmathtypes.h:164
#define TTMATH_DEC_SIGN
Definition: ttmathdec.h:64
void SetSign()
Definition: ttmathdec.h:165
constants used in the library
uint Pow(UInt< value_size > pow)
Definition: ttmathuint.h:2402
void Abs()
Definition: ttmathdec.h:177
UInt implements a big integer value without a sign.
Definition: ttmathuint.h:73
Dec(const char *s)
Definition: ttmathdec.h:82
unsigned char info
Definition: ttmathdec.h:56
Some objects used in multithreads environment.
unsigned int uint
Definition: ttmathtypes.h:163
Dec< value_size, dec_digits > & operator=(const char *s)
Definition: ttmathdec.h:89
void ClearInfoBit(unsigned char bit)
Definition: ttmathdec.h:114
Definition: ttmathdec.h:51
#define TTMATH_DEC_NAN
Definition: ttmathdec.h:71