Library for big numbers from http://www.ttmath.org/

Dependents:   PIDHeater82 Conceptcontroller_v_1_0 AlarmClockApp COG4050_adxl355_tilt ... more

TTMath is a small library which allows one to perform arithmetic operations with big unsigned integer, big signed integer and big floating point numbers. It provides standard mathematical operations like adding, subtracting, multiplying, dividing.

TTMath is BSD Licensed (new/modified BSD)

For more information about ttmath see http://www.ttmath.org/

Committer:
stevep
Date:
Tue Jul 30 18:43:48 2013 +0000
Revision:
0:04a9f72bbca7
v0.9.3 of ttmath

Who changed what in which revision?

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