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) 2006-2011, 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
stevep 0:04a9f72bbca7 39
stevep 0:04a9f72bbca7 40 #ifndef headerfilettmathint
stevep 0:04a9f72bbca7 41 #define headerfilettmathint
stevep 0:04a9f72bbca7 42
stevep 0:04a9f72bbca7 43 /*!
stevep 0:04a9f72bbca7 44 \file ttmathint.h
stevep 0:04a9f72bbca7 45 \brief template class Int<uint>
stevep 0:04a9f72bbca7 46 */
stevep 0:04a9f72bbca7 47
stevep 0:04a9f72bbca7 48 #include "ttmathuint.h"
stevep 0:04a9f72bbca7 49
stevep 0:04a9f72bbca7 50 namespace ttmath
stevep 0:04a9f72bbca7 51 {
stevep 0:04a9f72bbca7 52
stevep 0:04a9f72bbca7 53
stevep 0:04a9f72bbca7 54 /*!
stevep 0:04a9f72bbca7 55 \brief Int implements a big integer value with a sign
stevep 0:04a9f72bbca7 56
stevep 0:04a9f72bbca7 57 value_size - how many bytes specify our value
stevep 0:04a9f72bbca7 58 on 32bit platforms: value_size=1 -> 4 bytes -> 32 bits
stevep 0:04a9f72bbca7 59 on 64bit platforms: value_size=1 -> 8 bytes -> 64 bits
stevep 0:04a9f72bbca7 60 value_size = 1,2,3,4,5,6....
stevep 0:04a9f72bbca7 61 */
stevep 0:04a9f72bbca7 62 template<uint value_size>
stevep 0:04a9f72bbca7 63 class Int : public UInt<value_size>
stevep 0:04a9f72bbca7 64 {
stevep 0:04a9f72bbca7 65 public:
stevep 0:04a9f72bbca7 66
stevep 0:04a9f72bbca7 67 /*!
stevep 0:04a9f72bbca7 68 this method sets the max value which this class can hold
stevep 0:04a9f72bbca7 69 (all bits will be one besides the last one)
stevep 0:04a9f72bbca7 70 */
stevep 0:04a9f72bbca7 71 void SetMax()
stevep 0:04a9f72bbca7 72 {
stevep 0:04a9f72bbca7 73 UInt<value_size>::SetMax();
stevep 0:04a9f72bbca7 74 UInt<value_size>::table[value_size-1] = ~ TTMATH_UINT_HIGHEST_BIT;
stevep 0:04a9f72bbca7 75 }
stevep 0:04a9f72bbca7 76
stevep 0:04a9f72bbca7 77
stevep 0:04a9f72bbca7 78 /*!
stevep 0:04a9f72bbca7 79 this method sets the min value which this class can hold
stevep 0:04a9f72bbca7 80 (all bits will be zero besides the last one which is one)
stevep 0:04a9f72bbca7 81 */
stevep 0:04a9f72bbca7 82 void SetMin()
stevep 0:04a9f72bbca7 83 {
stevep 0:04a9f72bbca7 84 UInt<value_size>::SetZero();
stevep 0:04a9f72bbca7 85 UInt<value_size>::table[value_size-1] = TTMATH_UINT_HIGHEST_BIT;
stevep 0:04a9f72bbca7 86 }
stevep 0:04a9f72bbca7 87
stevep 0:04a9f72bbca7 88
stevep 0:04a9f72bbca7 89 /*!
stevep 0:04a9f72bbca7 90 this method sets -1 as the value
stevep 0:04a9f72bbca7 91 (-1 is equal the max value in an unsigned type)
stevep 0:04a9f72bbca7 92 */
stevep 0:04a9f72bbca7 93 void SetSignOne()
stevep 0:04a9f72bbca7 94 {
stevep 0:04a9f72bbca7 95 UInt<value_size>::SetMax();
stevep 0:04a9f72bbca7 96 }
stevep 0:04a9f72bbca7 97
stevep 0:04a9f72bbca7 98
stevep 0:04a9f72bbca7 99 /*!
stevep 0:04a9f72bbca7 100 we change the sign of the value
stevep 0:04a9f72bbca7 101
stevep 0:04a9f72bbca7 102 if it isn't possible to change the sign this method returns 1
stevep 0:04a9f72bbca7 103 else return 0 and changing the sign
stevep 0:04a9f72bbca7 104 */
stevep 0:04a9f72bbca7 105 uint ChangeSign()
stevep 0:04a9f72bbca7 106 {
stevep 0:04a9f72bbca7 107 /*
stevep 0:04a9f72bbca7 108 if the value is equal that one which has been returned from SetMin
stevep 0:04a9f72bbca7 109 (only the highest bit is set) that means we can't change sign
stevep 0:04a9f72bbca7 110 because the value is too big (bigger about one)
stevep 0:04a9f72bbca7 111
stevep 0:04a9f72bbca7 112 e.g. when value_size = 1 and value is -2147483648 we can't change it to the
stevep 0:04a9f72bbca7 113 2147483648 because the max value which can be held is 2147483647
stevep 0:04a9f72bbca7 114
stevep 0:04a9f72bbca7 115 we don't change the value and we're using this fact somewhere in some methods
stevep 0:04a9f72bbca7 116 (if we look on our value without the sign we get the correct value
stevep 0:04a9f72bbca7 117 eg. -2147483648 in Int<1> will be 2147483648 on the UInt<1> type)
stevep 0:04a9f72bbca7 118 */
stevep 0:04a9f72bbca7 119 if( UInt<value_size>::IsOnlyTheHighestBitSet() )
stevep 0:04a9f72bbca7 120 return 1;
stevep 0:04a9f72bbca7 121
stevep 0:04a9f72bbca7 122 UInt<value_size> temp(*this);
stevep 0:04a9f72bbca7 123 UInt<value_size>::SetZero();
stevep 0:04a9f72bbca7 124 UInt<value_size>::Sub(temp);
stevep 0:04a9f72bbca7 125
stevep 0:04a9f72bbca7 126 return 0;
stevep 0:04a9f72bbca7 127 }
stevep 0:04a9f72bbca7 128
stevep 0:04a9f72bbca7 129
stevep 0:04a9f72bbca7 130
stevep 0:04a9f72bbca7 131 /*!
stevep 0:04a9f72bbca7 132 this method sets the sign
stevep 0:04a9f72bbca7 133
stevep 0:04a9f72bbca7 134 e.g. 1 -> -1
stevep 0:04a9f72bbca7 135 -2 -> -2
stevep 0:04a9f72bbca7 136
stevep 0:04a9f72bbca7 137 from a positive value we make a negative value,
stevep 0:04a9f72bbca7 138 if the value is negative we do nothing
stevep 0:04a9f72bbca7 139 */
stevep 0:04a9f72bbca7 140 void SetSign()
stevep 0:04a9f72bbca7 141 {
stevep 0:04a9f72bbca7 142 if( IsSign() )
stevep 0:04a9f72bbca7 143 return;
stevep 0:04a9f72bbca7 144
stevep 0:04a9f72bbca7 145 ChangeSign();
stevep 0:04a9f72bbca7 146 }
stevep 0:04a9f72bbca7 147
stevep 0:04a9f72bbca7 148
stevep 0:04a9f72bbca7 149
stevep 0:04a9f72bbca7 150 /*!
stevep 0:04a9f72bbca7 151 this method returns true if there's the sign
stevep 0:04a9f72bbca7 152
stevep 0:04a9f72bbca7 153 (the highest bit will be converted to the bool)
stevep 0:04a9f72bbca7 154 */
stevep 0:04a9f72bbca7 155 bool IsSign() const
stevep 0:04a9f72bbca7 156 {
stevep 0:04a9f72bbca7 157 return UInt<value_size>::IsTheHighestBitSet();
stevep 0:04a9f72bbca7 158 }
stevep 0:04a9f72bbca7 159
stevep 0:04a9f72bbca7 160
stevep 0:04a9f72bbca7 161
stevep 0:04a9f72bbca7 162 /*!
stevep 0:04a9f72bbca7 163 it sets an absolute value
stevep 0:04a9f72bbca7 164
stevep 0:04a9f72bbca7 165 it can return carry (1) (look on ChangeSign() for details)
stevep 0:04a9f72bbca7 166 */
stevep 0:04a9f72bbca7 167 uint Abs()
stevep 0:04a9f72bbca7 168 {
stevep 0:04a9f72bbca7 169 if( !IsSign() )
stevep 0:04a9f72bbca7 170 return 0;
stevep 0:04a9f72bbca7 171
stevep 0:04a9f72bbca7 172 return ChangeSign();
stevep 0:04a9f72bbca7 173 }
stevep 0:04a9f72bbca7 174
stevep 0:04a9f72bbca7 175
stevep 0:04a9f72bbca7 176
stevep 0:04a9f72bbca7 177
stevep 0:04a9f72bbca7 178 /*!
stevep 0:04a9f72bbca7 179 *
stevep 0:04a9f72bbca7 180 * basic mathematic functions
stevep 0:04a9f72bbca7 181 *
stevep 0:04a9f72bbca7 182 */
stevep 0:04a9f72bbca7 183
stevep 0:04a9f72bbca7 184 private:
stevep 0:04a9f72bbca7 185
stevep 0:04a9f72bbca7 186 uint CorrectCarryAfterAdding(bool p1_is_sign, bool p2_is_sign)
stevep 0:04a9f72bbca7 187 {
stevep 0:04a9f72bbca7 188 if( !p1_is_sign && !p2_is_sign )
stevep 0:04a9f72bbca7 189 {
stevep 0:04a9f72bbca7 190 if( UInt<value_size>::IsTheHighestBitSet() )
stevep 0:04a9f72bbca7 191 return 1;
stevep 0:04a9f72bbca7 192 }
stevep 0:04a9f72bbca7 193
stevep 0:04a9f72bbca7 194 if( p1_is_sign && p2_is_sign )
stevep 0:04a9f72bbca7 195 {
stevep 0:04a9f72bbca7 196 if( ! UInt<value_size>::IsTheHighestBitSet() )
stevep 0:04a9f72bbca7 197 return 1;
stevep 0:04a9f72bbca7 198 }
stevep 0:04a9f72bbca7 199
stevep 0:04a9f72bbca7 200 return 0;
stevep 0:04a9f72bbca7 201 }
stevep 0:04a9f72bbca7 202
stevep 0:04a9f72bbca7 203
stevep 0:04a9f72bbca7 204 public:
stevep 0:04a9f72bbca7 205
stevep 0:04a9f72bbca7 206 /*!
stevep 0:04a9f72bbca7 207 this method adds two value with a sign and returns a carry
stevep 0:04a9f72bbca7 208
stevep 0:04a9f72bbca7 209 we're using methods from the base class because values are stored with U2
stevep 0:04a9f72bbca7 210 we must only make the carry correction
stevep 0:04a9f72bbca7 211
stevep 0:04a9f72bbca7 212 this = p1(=this) + p2
stevep 0:04a9f72bbca7 213
stevep 0:04a9f72bbca7 214 when p1>=0 i p2>=0 carry is set when the highest bit of value is set
stevep 0:04a9f72bbca7 215 when p1<0 i p2<0 carry is set when the highest bit of value is clear
stevep 0:04a9f72bbca7 216 when p1>=0 i p2<0 carry will never be set
stevep 0:04a9f72bbca7 217 when p1<0 i p2>=0 carry will never be set
stevep 0:04a9f72bbca7 218 */
stevep 0:04a9f72bbca7 219 uint Add(const Int<value_size> & ss2)
stevep 0:04a9f72bbca7 220 {
stevep 0:04a9f72bbca7 221 bool p1_is_sign = IsSign();
stevep 0:04a9f72bbca7 222 bool p2_is_sign = ss2.IsSign();
stevep 0:04a9f72bbca7 223
stevep 0:04a9f72bbca7 224 UInt<value_size>::Add(ss2);
stevep 0:04a9f72bbca7 225
stevep 0:04a9f72bbca7 226 return CorrectCarryAfterAdding(p1_is_sign, p2_is_sign);
stevep 0:04a9f72bbca7 227 }
stevep 0:04a9f72bbca7 228
stevep 0:04a9f72bbca7 229
stevep 0:04a9f72bbca7 230 /*!
stevep 0:04a9f72bbca7 231 this method adds one *unsigned* word (at a specific position)
stevep 0:04a9f72bbca7 232 and returns a carry (if it was)
stevep 0:04a9f72bbca7 233
stevep 0:04a9f72bbca7 234 look at a description in UInt<>::AddInt(...)
stevep 0:04a9f72bbca7 235 */
stevep 0:04a9f72bbca7 236 uint AddInt(uint value, uint index = 0)
stevep 0:04a9f72bbca7 237 {
stevep 0:04a9f72bbca7 238 bool p1_is_sign = IsSign();
stevep 0:04a9f72bbca7 239
stevep 0:04a9f72bbca7 240 UInt<value_size>::AddInt(value, index);
stevep 0:04a9f72bbca7 241
stevep 0:04a9f72bbca7 242 return CorrectCarryAfterAdding(p1_is_sign, false);
stevep 0:04a9f72bbca7 243 }
stevep 0:04a9f72bbca7 244
stevep 0:04a9f72bbca7 245
stevep 0:04a9f72bbca7 246 /*!
stevep 0:04a9f72bbca7 247 this method adds two *unsigned* words to the existing value
stevep 0:04a9f72bbca7 248 and these words begin on the 'index' position
stevep 0:04a9f72bbca7 249
stevep 0:04a9f72bbca7 250 index should be equal or smaller than value_size-2 (index <= value_size-2)
stevep 0:04a9f72bbca7 251 x1 - lower word, x2 - higher word
stevep 0:04a9f72bbca7 252
stevep 0:04a9f72bbca7 253 look at a description in UInt<>::AddTwoInts(...)
stevep 0:04a9f72bbca7 254 */
stevep 0:04a9f72bbca7 255 uint AddTwoInts(uint x2, uint x1, uint index)
stevep 0:04a9f72bbca7 256 {
stevep 0:04a9f72bbca7 257 bool p1_is_sign = IsSign();
stevep 0:04a9f72bbca7 258
stevep 0:04a9f72bbca7 259 UInt<value_size>::AddTwoInts(x2, x1, index);
stevep 0:04a9f72bbca7 260
stevep 0:04a9f72bbca7 261 return CorrectCarryAfterAdding(p1_is_sign, false);
stevep 0:04a9f72bbca7 262 }
stevep 0:04a9f72bbca7 263
stevep 0:04a9f72bbca7 264 private:
stevep 0:04a9f72bbca7 265
stevep 0:04a9f72bbca7 266 uint CorrectCarryAfterSubtracting(bool p1_is_sign, bool p2_is_sign)
stevep 0:04a9f72bbca7 267 {
stevep 0:04a9f72bbca7 268 if( !p1_is_sign && p2_is_sign )
stevep 0:04a9f72bbca7 269 {
stevep 0:04a9f72bbca7 270 if( UInt<value_size>::IsTheHighestBitSet() )
stevep 0:04a9f72bbca7 271 return 1;
stevep 0:04a9f72bbca7 272 }
stevep 0:04a9f72bbca7 273
stevep 0:04a9f72bbca7 274 if( p1_is_sign && !p2_is_sign )
stevep 0:04a9f72bbca7 275 {
stevep 0:04a9f72bbca7 276 if( ! UInt<value_size>::IsTheHighestBitSet() )
stevep 0:04a9f72bbca7 277 return 1;
stevep 0:04a9f72bbca7 278 }
stevep 0:04a9f72bbca7 279
stevep 0:04a9f72bbca7 280 return 0;
stevep 0:04a9f72bbca7 281 }
stevep 0:04a9f72bbca7 282
stevep 0:04a9f72bbca7 283 public:
stevep 0:04a9f72bbca7 284
stevep 0:04a9f72bbca7 285 /*!
stevep 0:04a9f72bbca7 286 this method subtracts two values with a sign
stevep 0:04a9f72bbca7 287
stevep 0:04a9f72bbca7 288 we don't use the previous Add because the method ChangeSign can
stevep 0:04a9f72bbca7 289 sometimes return carry
stevep 0:04a9f72bbca7 290
stevep 0:04a9f72bbca7 291 this = p1(=this) - p2
stevep 0:04a9f72bbca7 292
stevep 0:04a9f72bbca7 293 when p1>=0 i p2>=0 carry will never be set
stevep 0:04a9f72bbca7 294 when p1<0 i p2<0 carry will never be set
stevep 0:04a9f72bbca7 295 when p1>=0 i p2<0 carry is set when the highest bit of value is set
stevep 0:04a9f72bbca7 296 when p1<0 i p2>=0 carry is set when the highest bit of value is clear
stevep 0:04a9f72bbca7 297 */
stevep 0:04a9f72bbca7 298 uint Sub(const Int<value_size> & ss2)
stevep 0:04a9f72bbca7 299 {
stevep 0:04a9f72bbca7 300 bool p1_is_sign = IsSign();
stevep 0:04a9f72bbca7 301 bool p2_is_sign = ss2.IsSign();
stevep 0:04a9f72bbca7 302
stevep 0:04a9f72bbca7 303 UInt<value_size>::Sub(ss2);
stevep 0:04a9f72bbca7 304
stevep 0:04a9f72bbca7 305 return CorrectCarryAfterSubtracting(p1_is_sign, p2_is_sign);
stevep 0:04a9f72bbca7 306 }
stevep 0:04a9f72bbca7 307
stevep 0:04a9f72bbca7 308
stevep 0:04a9f72bbca7 309 /*!
stevep 0:04a9f72bbca7 310 this method subtracts one *unsigned* word (at a specific position)
stevep 0:04a9f72bbca7 311 and returns a carry (if it was)
stevep 0:04a9f72bbca7 312 */
stevep 0:04a9f72bbca7 313 uint SubInt(uint value, uint index = 0)
stevep 0:04a9f72bbca7 314 {
stevep 0:04a9f72bbca7 315 bool p1_is_sign = IsSign();
stevep 0:04a9f72bbca7 316
stevep 0:04a9f72bbca7 317 UInt<value_size>::SubInt(value, index);
stevep 0:04a9f72bbca7 318
stevep 0:04a9f72bbca7 319 return CorrectCarryAfterSubtracting(p1_is_sign, false);
stevep 0:04a9f72bbca7 320 }
stevep 0:04a9f72bbca7 321
stevep 0:04a9f72bbca7 322
stevep 0:04a9f72bbca7 323 /*!
stevep 0:04a9f72bbca7 324 this method adds one to the value and returns carry
stevep 0:04a9f72bbca7 325 */
stevep 0:04a9f72bbca7 326 uint AddOne()
stevep 0:04a9f72bbca7 327 {
stevep 0:04a9f72bbca7 328 bool p1_is_sign = IsSign();
stevep 0:04a9f72bbca7 329
stevep 0:04a9f72bbca7 330 UInt<value_size>::AddOne();
stevep 0:04a9f72bbca7 331
stevep 0:04a9f72bbca7 332 return CorrectCarryAfterAdding(p1_is_sign, false);
stevep 0:04a9f72bbca7 333 }
stevep 0:04a9f72bbca7 334
stevep 0:04a9f72bbca7 335
stevep 0:04a9f72bbca7 336 /*!
stevep 0:04a9f72bbca7 337 this method subtracts one from the value and returns carry
stevep 0:04a9f72bbca7 338 */
stevep 0:04a9f72bbca7 339 uint SubOne()
stevep 0:04a9f72bbca7 340 {
stevep 0:04a9f72bbca7 341 bool p1_is_sign = IsSign();
stevep 0:04a9f72bbca7 342
stevep 0:04a9f72bbca7 343 UInt<value_size>::SubOne();
stevep 0:04a9f72bbca7 344
stevep 0:04a9f72bbca7 345 return CorrectCarryAfterSubtracting(p1_is_sign, false);
stevep 0:04a9f72bbca7 346 }
stevep 0:04a9f72bbca7 347
stevep 0:04a9f72bbca7 348
stevep 0:04a9f72bbca7 349 private:
stevep 0:04a9f72bbca7 350
stevep 0:04a9f72bbca7 351
stevep 0:04a9f72bbca7 352 uint CheckMinCarry(bool ss1_is_sign, bool ss2_is_sign)
stevep 0:04a9f72bbca7 353 {
stevep 0:04a9f72bbca7 354 /*
stevep 0:04a9f72bbca7 355 we have to examine the sign of the result now
stevep 0:04a9f72bbca7 356 but if the result is with the sign then:
stevep 0:04a9f72bbca7 357 1. if the signs were the same that means the result is too big
stevep 0:04a9f72bbca7 358 (the result must be without a sign)
stevep 0:04a9f72bbca7 359 2. if the signs were different that means if the result
stevep 0:04a9f72bbca7 360 is different from that one which has been returned from SetMin()
stevep 0:04a9f72bbca7 361 that is carry (result too big) but if the result is equal SetMin()
stevep 0:04a9f72bbca7 362 there'll be ok (and the next SetSign will has no effect because
stevep 0:04a9f72bbca7 363 the value is actually negative -- look at description of that case
stevep 0:04a9f72bbca7 364 in ChangeSign())
stevep 0:04a9f72bbca7 365 */
stevep 0:04a9f72bbca7 366 if( IsSign() )
stevep 0:04a9f72bbca7 367 {
stevep 0:04a9f72bbca7 368 if( ss1_is_sign != ss2_is_sign )
stevep 0:04a9f72bbca7 369 {
stevep 0:04a9f72bbca7 370 /*
stevep 0:04a9f72bbca7 371 there can be one case where signs are different and
stevep 0:04a9f72bbca7 372 the result will be equal the value from SetMin() (only the highest bit is set)
stevep 0:04a9f72bbca7 373 (this situation is ok)
stevep 0:04a9f72bbca7 374 */
stevep 0:04a9f72bbca7 375 if( !UInt<value_size>::IsOnlyTheHighestBitSet() )
stevep 0:04a9f72bbca7 376 return 1;
stevep 0:04a9f72bbca7 377 }
stevep 0:04a9f72bbca7 378 else
stevep 0:04a9f72bbca7 379 {
stevep 0:04a9f72bbca7 380 // signs were the same
stevep 0:04a9f72bbca7 381 return 1;
stevep 0:04a9f72bbca7 382 }
stevep 0:04a9f72bbca7 383 }
stevep 0:04a9f72bbca7 384
stevep 0:04a9f72bbca7 385 return 0;
stevep 0:04a9f72bbca7 386 }
stevep 0:04a9f72bbca7 387
stevep 0:04a9f72bbca7 388
stevep 0:04a9f72bbca7 389 public:
stevep 0:04a9f72bbca7 390
stevep 0:04a9f72bbca7 391
stevep 0:04a9f72bbca7 392 /*!
stevep 0:04a9f72bbca7 393 multiplication: this = this * ss2
stevep 0:04a9f72bbca7 394
stevep 0:04a9f72bbca7 395 it can return a carry
stevep 0:04a9f72bbca7 396 */
stevep 0:04a9f72bbca7 397 uint MulInt(sint ss2)
stevep 0:04a9f72bbca7 398 {
stevep 0:04a9f72bbca7 399 bool ss1_is_sign, ss2_is_sign;
stevep 0:04a9f72bbca7 400 uint c;
stevep 0:04a9f72bbca7 401
stevep 0:04a9f72bbca7 402 ss1_is_sign = IsSign();
stevep 0:04a9f72bbca7 403
stevep 0:04a9f72bbca7 404 /*
stevep 0:04a9f72bbca7 405 we don't have to check the carry from Abs (values will be correct
stevep 0:04a9f72bbca7 406 because next we're using the method MulInt from the base class UInt
stevep 0:04a9f72bbca7 407 which is without a sign)
stevep 0:04a9f72bbca7 408 */
stevep 0:04a9f72bbca7 409 Abs();
stevep 0:04a9f72bbca7 410
stevep 0:04a9f72bbca7 411 if( ss2 < 0 )
stevep 0:04a9f72bbca7 412 {
stevep 0:04a9f72bbca7 413 ss2 = -ss2;
stevep 0:04a9f72bbca7 414 ss2_is_sign = true;
stevep 0:04a9f72bbca7 415 }
stevep 0:04a9f72bbca7 416 else
stevep 0:04a9f72bbca7 417 {
stevep 0:04a9f72bbca7 418 ss2_is_sign = false;
stevep 0:04a9f72bbca7 419 }
stevep 0:04a9f72bbca7 420
stevep 0:04a9f72bbca7 421 c = UInt<value_size>::MulInt((uint)ss2);
stevep 0:04a9f72bbca7 422 c += CheckMinCarry(ss1_is_sign, ss2_is_sign);
stevep 0:04a9f72bbca7 423
stevep 0:04a9f72bbca7 424 if( ss1_is_sign != ss2_is_sign )
stevep 0:04a9f72bbca7 425 SetSign();
stevep 0:04a9f72bbca7 426
stevep 0:04a9f72bbca7 427 return c;
stevep 0:04a9f72bbca7 428 }
stevep 0:04a9f72bbca7 429
stevep 0:04a9f72bbca7 430
stevep 0:04a9f72bbca7 431
stevep 0:04a9f72bbca7 432 /*!
stevep 0:04a9f72bbca7 433 multiplication this = this * ss2
stevep 0:04a9f72bbca7 434
stevep 0:04a9f72bbca7 435 it returns carry if the result is too big
stevep 0:04a9f72bbca7 436 (we're using the method from the base class but we have to make
stevep 0:04a9f72bbca7 437 one correction in account of signs)
stevep 0:04a9f72bbca7 438 */
stevep 0:04a9f72bbca7 439 uint Mul(Int<value_size> ss2)
stevep 0:04a9f72bbca7 440 {
stevep 0:04a9f72bbca7 441 bool ss1_is_sign, ss2_is_sign;
stevep 0:04a9f72bbca7 442 uint c;
stevep 0:04a9f72bbca7 443
stevep 0:04a9f72bbca7 444 ss1_is_sign = IsSign();
stevep 0:04a9f72bbca7 445 ss2_is_sign = ss2.IsSign();
stevep 0:04a9f72bbca7 446
stevep 0:04a9f72bbca7 447 /*
stevep 0:04a9f72bbca7 448 we don't have to check the carry from Abs (values will be correct
stevep 0:04a9f72bbca7 449 because next we're using the method Mul from the base class UInt
stevep 0:04a9f72bbca7 450 which is without a sign)
stevep 0:04a9f72bbca7 451 */
stevep 0:04a9f72bbca7 452 Abs();
stevep 0:04a9f72bbca7 453 ss2.Abs();
stevep 0:04a9f72bbca7 454
stevep 0:04a9f72bbca7 455 c = UInt<value_size>::Mul(ss2);
stevep 0:04a9f72bbca7 456 c += CheckMinCarry(ss1_is_sign, ss2_is_sign);
stevep 0:04a9f72bbca7 457
stevep 0:04a9f72bbca7 458 if( ss1_is_sign != ss2_is_sign )
stevep 0:04a9f72bbca7 459 SetSign();
stevep 0:04a9f72bbca7 460
stevep 0:04a9f72bbca7 461 return c;
stevep 0:04a9f72bbca7 462 }
stevep 0:04a9f72bbca7 463
stevep 0:04a9f72bbca7 464
stevep 0:04a9f72bbca7 465 /*!
stevep 0:04a9f72bbca7 466 division this = this / ss2
stevep 0:04a9f72bbca7 467 returned values:
stevep 0:04a9f72bbca7 468 0 - ok
stevep 0:04a9f72bbca7 469 1 - division by zero
stevep 0:04a9f72bbca7 470
stevep 0:04a9f72bbca7 471 for example: (result means 'this')
stevep 0:04a9f72bbca7 472 20 / 3 --> result: 6 remainder: 2
stevep 0:04a9f72bbca7 473 -20 / 3 --> result: -6 remainder: -2
stevep 0:04a9f72bbca7 474 20 / -3 --> result: -6 remainder: 2
stevep 0:04a9f72bbca7 475 -20 / -3 --> result: 6 remainder: -2
stevep 0:04a9f72bbca7 476
stevep 0:04a9f72bbca7 477 in other words: this(old) = ss2 * this(new)(result) + remainder
stevep 0:04a9f72bbca7 478 */
stevep 0:04a9f72bbca7 479 uint Div(Int<value_size> ss2, Int<value_size> * remainder = 0)
stevep 0:04a9f72bbca7 480 {
stevep 0:04a9f72bbca7 481 bool ss1_is_sign, ss2_is_sign;
stevep 0:04a9f72bbca7 482
stevep 0:04a9f72bbca7 483 ss1_is_sign = IsSign();
stevep 0:04a9f72bbca7 484 ss2_is_sign = ss2.IsSign();
stevep 0:04a9f72bbca7 485
stevep 0:04a9f72bbca7 486 /*
stevep 0:04a9f72bbca7 487 we don't have to test the carry from Abs as well as in Mul
stevep 0:04a9f72bbca7 488 */
stevep 0:04a9f72bbca7 489 Abs();
stevep 0:04a9f72bbca7 490 ss2.Abs();
stevep 0:04a9f72bbca7 491
stevep 0:04a9f72bbca7 492 uint c = UInt<value_size>::Div(ss2, remainder);
stevep 0:04a9f72bbca7 493
stevep 0:04a9f72bbca7 494 if( ss1_is_sign != ss2_is_sign )
stevep 0:04a9f72bbca7 495 SetSign();
stevep 0:04a9f72bbca7 496
stevep 0:04a9f72bbca7 497 if( ss1_is_sign && remainder )
stevep 0:04a9f72bbca7 498 remainder->SetSign();
stevep 0:04a9f72bbca7 499
stevep 0:04a9f72bbca7 500 return c;
stevep 0:04a9f72bbca7 501 }
stevep 0:04a9f72bbca7 502
stevep 0:04a9f72bbca7 503 uint Div(const Int<value_size> & ss2, Int<value_size> & remainder)
stevep 0:04a9f72bbca7 504 {
stevep 0:04a9f72bbca7 505 return Div(ss2, &remainder);
stevep 0:04a9f72bbca7 506 }
stevep 0:04a9f72bbca7 507
stevep 0:04a9f72bbca7 508
stevep 0:04a9f72bbca7 509 /*!
stevep 0:04a9f72bbca7 510 division this = this / ss2 (ss2 is int)
stevep 0:04a9f72bbca7 511 returned values:
stevep 0:04a9f72bbca7 512 0 - ok
stevep 0:04a9f72bbca7 513 1 - division by zero
stevep 0:04a9f72bbca7 514
stevep 0:04a9f72bbca7 515 for example: (result means 'this')
stevep 0:04a9f72bbca7 516 20 / 3 --> result: 6 remainder: 2
stevep 0:04a9f72bbca7 517 -20 / 3 --> result: -6 remainder: -2
stevep 0:04a9f72bbca7 518 20 / -3 --> result: -6 remainder: 2
stevep 0:04a9f72bbca7 519 -20 / -3 --> result: 6 remainder: -2
stevep 0:04a9f72bbca7 520
stevep 0:04a9f72bbca7 521 in other words: this(old) = ss2 * this(new)(result) + remainder
stevep 0:04a9f72bbca7 522 */
stevep 0:04a9f72bbca7 523 uint DivInt(sint ss2, sint * remainder = 0)
stevep 0:04a9f72bbca7 524 {
stevep 0:04a9f72bbca7 525 bool ss1_is_sign, ss2_is_sign;
stevep 0:04a9f72bbca7 526
stevep 0:04a9f72bbca7 527 ss1_is_sign = IsSign();
stevep 0:04a9f72bbca7 528
stevep 0:04a9f72bbca7 529 /*
stevep 0:04a9f72bbca7 530 we don't have to test the carry from Abs as well as in Mul
stevep 0:04a9f72bbca7 531 */
stevep 0:04a9f72bbca7 532 Abs();
stevep 0:04a9f72bbca7 533
stevep 0:04a9f72bbca7 534 if( ss2 < 0 )
stevep 0:04a9f72bbca7 535 {
stevep 0:04a9f72bbca7 536 ss2 = -ss2;
stevep 0:04a9f72bbca7 537 ss2_is_sign = true;
stevep 0:04a9f72bbca7 538 }
stevep 0:04a9f72bbca7 539 else
stevep 0:04a9f72bbca7 540 {
stevep 0:04a9f72bbca7 541 ss2_is_sign = false;
stevep 0:04a9f72bbca7 542 }
stevep 0:04a9f72bbca7 543
stevep 0:04a9f72bbca7 544 uint rem;
stevep 0:04a9f72bbca7 545 uint c = UInt<value_size>::DivInt((uint)ss2, &rem);
stevep 0:04a9f72bbca7 546
stevep 0:04a9f72bbca7 547 if( ss1_is_sign != ss2_is_sign )
stevep 0:04a9f72bbca7 548 SetSign();
stevep 0:04a9f72bbca7 549
stevep 0:04a9f72bbca7 550 if( remainder )
stevep 0:04a9f72bbca7 551 {
stevep 0:04a9f72bbca7 552 if( ss1_is_sign )
stevep 0:04a9f72bbca7 553 *remainder = -sint(rem);
stevep 0:04a9f72bbca7 554 else
stevep 0:04a9f72bbca7 555 *remainder = sint(rem);
stevep 0:04a9f72bbca7 556 }
stevep 0:04a9f72bbca7 557
stevep 0:04a9f72bbca7 558 return c;
stevep 0:04a9f72bbca7 559 }
stevep 0:04a9f72bbca7 560
stevep 0:04a9f72bbca7 561
stevep 0:04a9f72bbca7 562 uint DivInt(sint ss2, sint & remainder)
stevep 0:04a9f72bbca7 563 {
stevep 0:04a9f72bbca7 564 return DivInt(ss2, &remainder);
stevep 0:04a9f72bbca7 565 }
stevep 0:04a9f72bbca7 566
stevep 0:04a9f72bbca7 567
stevep 0:04a9f72bbca7 568 private:
stevep 0:04a9f72bbca7 569
stevep 0:04a9f72bbca7 570
stevep 0:04a9f72bbca7 571 /*!
stevep 0:04a9f72bbca7 572 power this = this ^ pow
stevep 0:04a9f72bbca7 573 this can be negative
stevep 0:04a9f72bbca7 574 pow is >= 0
stevep 0:04a9f72bbca7 575 */
stevep 0:04a9f72bbca7 576 uint Pow2(const Int<value_size> & pow)
stevep 0:04a9f72bbca7 577 {
stevep 0:04a9f72bbca7 578 bool was_sign = IsSign();
stevep 0:04a9f72bbca7 579 uint c = 0;
stevep 0:04a9f72bbca7 580
stevep 0:04a9f72bbca7 581 if( was_sign )
stevep 0:04a9f72bbca7 582 c += Abs();
stevep 0:04a9f72bbca7 583
stevep 0:04a9f72bbca7 584 uint c_temp = UInt<value_size>::Pow(pow);
stevep 0:04a9f72bbca7 585 if( c_temp > 0 )
stevep 0:04a9f72bbca7 586 return c_temp; // c_temp can be: 0, 1 or 2
stevep 0:04a9f72bbca7 587
stevep 0:04a9f72bbca7 588 if( was_sign && (pow.table[0] & 1) == 1 )
stevep 0:04a9f72bbca7 589 // negative value to the power of odd number is negative
stevep 0:04a9f72bbca7 590 c += ChangeSign();
stevep 0:04a9f72bbca7 591
stevep 0:04a9f72bbca7 592 return (c==0)? 0 : 1;
stevep 0:04a9f72bbca7 593 }
stevep 0:04a9f72bbca7 594
stevep 0:04a9f72bbca7 595
stevep 0:04a9f72bbca7 596 public:
stevep 0:04a9f72bbca7 597
stevep 0:04a9f72bbca7 598
stevep 0:04a9f72bbca7 599 /*!
stevep 0:04a9f72bbca7 600 power this = this ^ pow
stevep 0:04a9f72bbca7 601
stevep 0:04a9f72bbca7 602 return values:
stevep 0:04a9f72bbca7 603 0 - ok
stevep 0:04a9f72bbca7 604 1 - carry
stevep 0:04a9f72bbca7 605 2 - incorrect arguments 0^0 or 0^(-something)
stevep 0:04a9f72bbca7 606 */
stevep 0:04a9f72bbca7 607 uint Pow(Int<value_size> pow)
stevep 0:04a9f72bbca7 608 {
stevep 0:04a9f72bbca7 609 if( !pow.IsSign() )
stevep 0:04a9f72bbca7 610 return Pow2(pow);
stevep 0:04a9f72bbca7 611
stevep 0:04a9f72bbca7 612 if( UInt<value_size>::IsZero() )
stevep 0:04a9f72bbca7 613 // if 'pow' is negative then
stevep 0:04a9f72bbca7 614 // 'this' must be different from zero
stevep 0:04a9f72bbca7 615 return 2;
stevep 0:04a9f72bbca7 616
stevep 0:04a9f72bbca7 617 if( pow.ChangeSign() )
stevep 0:04a9f72bbca7 618 return 1;
stevep 0:04a9f72bbca7 619
stevep 0:04a9f72bbca7 620 Int<value_size> t(*this);
stevep 0:04a9f72bbca7 621 uint c_temp = t.Pow2(pow);
stevep 0:04a9f72bbca7 622 if( c_temp > 0 )
stevep 0:04a9f72bbca7 623 return c_temp;
stevep 0:04a9f72bbca7 624
stevep 0:04a9f72bbca7 625 UInt<value_size>::SetOne();
stevep 0:04a9f72bbca7 626 if( Div(t) )
stevep 0:04a9f72bbca7 627 return 1;
stevep 0:04a9f72bbca7 628
stevep 0:04a9f72bbca7 629 return 0;
stevep 0:04a9f72bbca7 630 }
stevep 0:04a9f72bbca7 631
stevep 0:04a9f72bbca7 632
stevep 0:04a9f72bbca7 633
stevep 0:04a9f72bbca7 634 /*!
stevep 0:04a9f72bbca7 635 *
stevep 0:04a9f72bbca7 636 * convertion methods
stevep 0:04a9f72bbca7 637 *
stevep 0:04a9f72bbca7 638 */
stevep 0:04a9f72bbca7 639 private:
stevep 0:04a9f72bbca7 640
stevep 0:04a9f72bbca7 641
stevep 0:04a9f72bbca7 642 /*!
stevep 0:04a9f72bbca7 643 an auxiliary method for converting both from UInt and Int
stevep 0:04a9f72bbca7 644 */
stevep 0:04a9f72bbca7 645 template<uint argument_size>
stevep 0:04a9f72bbca7 646 uint FromUIntOrInt(const UInt<argument_size> & p, bool UInt_type)
stevep 0:04a9f72bbca7 647 {
stevep 0:04a9f72bbca7 648 uint min_size = (value_size < argument_size)? value_size : argument_size;
stevep 0:04a9f72bbca7 649 uint i;
stevep 0:04a9f72bbca7 650
stevep 0:04a9f72bbca7 651 for(i=0 ; i<min_size ; ++i)
stevep 0:04a9f72bbca7 652 UInt<value_size>::table[i] = p.table[i];
stevep 0:04a9f72bbca7 653
stevep 0:04a9f72bbca7 654
stevep 0:04a9f72bbca7 655 if( value_size > argument_size )
stevep 0:04a9f72bbca7 656 {
stevep 0:04a9f72bbca7 657 uint fill;
stevep 0:04a9f72bbca7 658
stevep 0:04a9f72bbca7 659 if( UInt_type )
stevep 0:04a9f72bbca7 660 fill = 0;
stevep 0:04a9f72bbca7 661 else
stevep 0:04a9f72bbca7 662 fill = (p.table[argument_size-1] & TTMATH_UINT_HIGHEST_BIT)?
stevep 0:04a9f72bbca7 663 TTMATH_UINT_MAX_VALUE : 0;
stevep 0:04a9f72bbca7 664
stevep 0:04a9f72bbca7 665 // 'this' is longer than 'p'
stevep 0:04a9f72bbca7 666 for( ; i<value_size ; ++i)
stevep 0:04a9f72bbca7 667 UInt<value_size>::table[i] = fill;
stevep 0:04a9f72bbca7 668 }
stevep 0:04a9f72bbca7 669 else
stevep 0:04a9f72bbca7 670 {
stevep 0:04a9f72bbca7 671 uint test = (UInt<value_size>::table[value_size-1] & TTMATH_UINT_HIGHEST_BIT)?
stevep 0:04a9f72bbca7 672 TTMATH_UINT_MAX_VALUE : 0;
stevep 0:04a9f72bbca7 673
stevep 0:04a9f72bbca7 674 if( UInt_type && test!=0 )
stevep 0:04a9f72bbca7 675 return 1;
stevep 0:04a9f72bbca7 676
stevep 0:04a9f72bbca7 677 for( ; i<argument_size ; ++i)
stevep 0:04a9f72bbca7 678 if( p.table[i] != test )
stevep 0:04a9f72bbca7 679 return 1;
stevep 0:04a9f72bbca7 680 }
stevep 0:04a9f72bbca7 681
stevep 0:04a9f72bbca7 682 return 0;
stevep 0:04a9f72bbca7 683 }
stevep 0:04a9f72bbca7 684
stevep 0:04a9f72bbca7 685 public:
stevep 0:04a9f72bbca7 686
stevep 0:04a9f72bbca7 687 /*!
stevep 0:04a9f72bbca7 688 this method converts an Int<another_size> type into this class
stevep 0:04a9f72bbca7 689
stevep 0:04a9f72bbca7 690 this operation has mainly sense if the value from p
stevep 0:04a9f72bbca7 691 can be held in this type
stevep 0:04a9f72bbca7 692
stevep 0:04a9f72bbca7 693 it returns a carry if the value 'p' is too big
stevep 0:04a9f72bbca7 694 */
stevep 0:04a9f72bbca7 695 template<uint argument_size>
stevep 0:04a9f72bbca7 696 uint FromInt(const Int<argument_size> & p)
stevep 0:04a9f72bbca7 697 {
stevep 0:04a9f72bbca7 698 return FromUIntOrInt(p, false);
stevep 0:04a9f72bbca7 699 }
stevep 0:04a9f72bbca7 700
stevep 0:04a9f72bbca7 701
stevep 0:04a9f72bbca7 702 /*!
stevep 0:04a9f72bbca7 703 this method converts the sint type into this class
stevep 0:04a9f72bbca7 704 */
stevep 0:04a9f72bbca7 705 uint FromInt(sint value)
stevep 0:04a9f72bbca7 706 {
stevep 0:04a9f72bbca7 707 uint fill = ( value<0 ) ? TTMATH_UINT_MAX_VALUE : 0;
stevep 0:04a9f72bbca7 708
stevep 0:04a9f72bbca7 709 for(uint i=1 ; i<value_size ; ++i)
stevep 0:04a9f72bbca7 710 UInt<value_size>::table[i] = fill;
stevep 0:04a9f72bbca7 711
stevep 0:04a9f72bbca7 712 UInt<value_size>::table[0] = uint(value);
stevep 0:04a9f72bbca7 713
stevep 0:04a9f72bbca7 714 // there'll never be a carry here
stevep 0:04a9f72bbca7 715 return 0;
stevep 0:04a9f72bbca7 716 }
stevep 0:04a9f72bbca7 717
stevep 0:04a9f72bbca7 718
stevep 0:04a9f72bbca7 719 /*!
stevep 0:04a9f72bbca7 720 this method converts UInt<another_size> into this class
stevep 0:04a9f72bbca7 721 */
stevep 0:04a9f72bbca7 722 template<uint argument_size>
stevep 0:04a9f72bbca7 723 uint FromUInt(const UInt<argument_size> & p)
stevep 0:04a9f72bbca7 724 {
stevep 0:04a9f72bbca7 725 return FromUIntOrInt(p, true);
stevep 0:04a9f72bbca7 726 }
stevep 0:04a9f72bbca7 727
stevep 0:04a9f72bbca7 728
stevep 0:04a9f72bbca7 729 /*!
stevep 0:04a9f72bbca7 730 this method converts UInt<another_size> into this class
stevep 0:04a9f72bbca7 731 */
stevep 0:04a9f72bbca7 732 template<uint argument_size>
stevep 0:04a9f72bbca7 733 uint FromInt(const UInt<argument_size> & p)
stevep 0:04a9f72bbca7 734 {
stevep 0:04a9f72bbca7 735 return FromUIntOrInt(p, true);
stevep 0:04a9f72bbca7 736 }
stevep 0:04a9f72bbca7 737
stevep 0:04a9f72bbca7 738
stevep 0:04a9f72bbca7 739 /*!
stevep 0:04a9f72bbca7 740 this method converts the uint type into this class
stevep 0:04a9f72bbca7 741 */
stevep 0:04a9f72bbca7 742 uint FromUInt(uint value)
stevep 0:04a9f72bbca7 743 {
stevep 0:04a9f72bbca7 744 for(uint i=1 ; i<value_size ; ++i)
stevep 0:04a9f72bbca7 745 UInt<value_size>::table[i] = 0;
stevep 0:04a9f72bbca7 746
stevep 0:04a9f72bbca7 747 UInt<value_size>::table[0] = value;
stevep 0:04a9f72bbca7 748
stevep 0:04a9f72bbca7 749 // there can be a carry here when the size of this value is equal one word
stevep 0:04a9f72bbca7 750 // and the 'value' has the highest bit set
stevep 0:04a9f72bbca7 751 if( value_size==1 && (value & TTMATH_UINT_HIGHEST_BIT)!=0 )
stevep 0:04a9f72bbca7 752 return 1;
stevep 0:04a9f72bbca7 753
stevep 0:04a9f72bbca7 754 return 0;
stevep 0:04a9f72bbca7 755 }
stevep 0:04a9f72bbca7 756
stevep 0:04a9f72bbca7 757
stevep 0:04a9f72bbca7 758 /*!
stevep 0:04a9f72bbca7 759 this method converts the uint type into this class
stevep 0:04a9f72bbca7 760 */
stevep 0:04a9f72bbca7 761 uint FromInt(uint value)
stevep 0:04a9f72bbca7 762 {
stevep 0:04a9f72bbca7 763 return FromUInt(value);
stevep 0:04a9f72bbca7 764 }
stevep 0:04a9f72bbca7 765
stevep 0:04a9f72bbca7 766
stevep 0:04a9f72bbca7 767 /*!
stevep 0:04a9f72bbca7 768 the default assignment operator
stevep 0:04a9f72bbca7 769 */
stevep 0:04a9f72bbca7 770 Int<value_size> & operator=(const Int<value_size> & p)
stevep 0:04a9f72bbca7 771 {
stevep 0:04a9f72bbca7 772 FromInt(p);
stevep 0:04a9f72bbca7 773
stevep 0:04a9f72bbca7 774 return *this;
stevep 0:04a9f72bbca7 775 }
stevep 0:04a9f72bbca7 776
stevep 0:04a9f72bbca7 777
stevep 0:04a9f72bbca7 778 /*!
stevep 0:04a9f72bbca7 779 this operator converts an Int<another_size> type to this class
stevep 0:04a9f72bbca7 780
stevep 0:04a9f72bbca7 781 it doesn't return a carry
stevep 0:04a9f72bbca7 782 */
stevep 0:04a9f72bbca7 783 template<uint argument_size>
stevep 0:04a9f72bbca7 784 Int<value_size> & operator=(const Int<argument_size> & p)
stevep 0:04a9f72bbca7 785 {
stevep 0:04a9f72bbca7 786 FromInt(p);
stevep 0:04a9f72bbca7 787
stevep 0:04a9f72bbca7 788 return *this;
stevep 0:04a9f72bbca7 789 }
stevep 0:04a9f72bbca7 790
stevep 0:04a9f72bbca7 791
stevep 0:04a9f72bbca7 792 /*!
stevep 0:04a9f72bbca7 793 this method converts the sint type to this class
stevep 0:04a9f72bbca7 794 */
stevep 0:04a9f72bbca7 795 Int<value_size> & operator=(sint i)
stevep 0:04a9f72bbca7 796 {
stevep 0:04a9f72bbca7 797 FromInt(i);
stevep 0:04a9f72bbca7 798
stevep 0:04a9f72bbca7 799 return *this;
stevep 0:04a9f72bbca7 800 }
stevep 0:04a9f72bbca7 801
stevep 0:04a9f72bbca7 802
stevep 0:04a9f72bbca7 803 /*!
stevep 0:04a9f72bbca7 804 a constructor for converting the uint to this class
stevep 0:04a9f72bbca7 805 */
stevep 0:04a9f72bbca7 806 Int(sint i)
stevep 0:04a9f72bbca7 807 {
stevep 0:04a9f72bbca7 808 FromInt(i);
stevep 0:04a9f72bbca7 809 }
stevep 0:04a9f72bbca7 810
stevep 0:04a9f72bbca7 811
stevep 0:04a9f72bbca7 812 /*!
stevep 0:04a9f72bbca7 813 a copy constructor
stevep 0:04a9f72bbca7 814 */
stevep 0:04a9f72bbca7 815 Int(const Int<value_size> & u)
stevep 0:04a9f72bbca7 816 {
stevep 0:04a9f72bbca7 817 FromInt(u);
stevep 0:04a9f72bbca7 818 }
stevep 0:04a9f72bbca7 819
stevep 0:04a9f72bbca7 820
stevep 0:04a9f72bbca7 821 /*!
stevep 0:04a9f72bbca7 822 a constructor for copying from another types
stevep 0:04a9f72bbca7 823 */
stevep 0:04a9f72bbca7 824 template<uint argument_size>
stevep 0:04a9f72bbca7 825 Int(const Int<argument_size> & u)
stevep 0:04a9f72bbca7 826 {
stevep 0:04a9f72bbca7 827 // look that 'size' we still set as 'value_size' and not as u.value_size
stevep 0:04a9f72bbca7 828 FromInt(u);
stevep 0:04a9f72bbca7 829 }
stevep 0:04a9f72bbca7 830
stevep 0:04a9f72bbca7 831
stevep 0:04a9f72bbca7 832
stevep 0:04a9f72bbca7 833 /*!
stevep 0:04a9f72bbca7 834 this operator converts an UInt<another_size> type to this class
stevep 0:04a9f72bbca7 835
stevep 0:04a9f72bbca7 836 it doesn't return a carry
stevep 0:04a9f72bbca7 837 */
stevep 0:04a9f72bbca7 838 template<uint argument_size>
stevep 0:04a9f72bbca7 839 Int<value_size> & operator=(const UInt<argument_size> & p)
stevep 0:04a9f72bbca7 840 {
stevep 0:04a9f72bbca7 841 FromUInt(p);
stevep 0:04a9f72bbca7 842
stevep 0:04a9f72bbca7 843 return *this;
stevep 0:04a9f72bbca7 844 }
stevep 0:04a9f72bbca7 845
stevep 0:04a9f72bbca7 846
stevep 0:04a9f72bbca7 847 /*!
stevep 0:04a9f72bbca7 848 this method converts the Uint type to this class
stevep 0:04a9f72bbca7 849 */
stevep 0:04a9f72bbca7 850 Int<value_size> & operator=(uint i)
stevep 0:04a9f72bbca7 851 {
stevep 0:04a9f72bbca7 852 FromUInt(i);
stevep 0:04a9f72bbca7 853
stevep 0:04a9f72bbca7 854 return *this;
stevep 0:04a9f72bbca7 855 }
stevep 0:04a9f72bbca7 856
stevep 0:04a9f72bbca7 857
stevep 0:04a9f72bbca7 858 /*!
stevep 0:04a9f72bbca7 859 a constructor for converting the uint to this class
stevep 0:04a9f72bbca7 860 */
stevep 0:04a9f72bbca7 861 Int(uint i)
stevep 0:04a9f72bbca7 862 {
stevep 0:04a9f72bbca7 863 FromUInt(i);
stevep 0:04a9f72bbca7 864 }
stevep 0:04a9f72bbca7 865
stevep 0:04a9f72bbca7 866
stevep 0:04a9f72bbca7 867 /*!
stevep 0:04a9f72bbca7 868 a constructor for copying from another types
stevep 0:04a9f72bbca7 869 */
stevep 0:04a9f72bbca7 870 template<uint argument_size>
stevep 0:04a9f72bbca7 871 Int(const UInt<argument_size> & u)
stevep 0:04a9f72bbca7 872 {
stevep 0:04a9f72bbca7 873 // look that 'size' we still set as 'value_size' and not as u.value_size
stevep 0:04a9f72bbca7 874 FromUInt(u);
stevep 0:04a9f72bbca7 875 }
stevep 0:04a9f72bbca7 876
stevep 0:04a9f72bbca7 877
stevep 0:04a9f72bbca7 878
stevep 0:04a9f72bbca7 879 #ifdef TTMATH_PLATFORM32
stevep 0:04a9f72bbca7 880
stevep 0:04a9f72bbca7 881
stevep 0:04a9f72bbca7 882 /*!
stevep 0:04a9f72bbca7 883 this method converts unsigned 64 bit int type to this class
stevep 0:04a9f72bbca7 884 ***this method is created only on a 32bit platform***
stevep 0:04a9f72bbca7 885 */
stevep 0:04a9f72bbca7 886 uint FromUInt(ulint n)
stevep 0:04a9f72bbca7 887 {
stevep 0:04a9f72bbca7 888 uint c = UInt<value_size>::FromUInt(n);
stevep 0:04a9f72bbca7 889
stevep 0:04a9f72bbca7 890 if( c )
stevep 0:04a9f72bbca7 891 return 1;
stevep 0:04a9f72bbca7 892
stevep 0:04a9f72bbca7 893 if( value_size == 1 )
stevep 0:04a9f72bbca7 894 return ((UInt<value_size>::table[0] & TTMATH_UINT_HIGHEST_BIT) == 0) ? 0 : 1;
stevep 0:04a9f72bbca7 895
stevep 0:04a9f72bbca7 896 if( value_size == 2 )
stevep 0:04a9f72bbca7 897 return ((UInt<value_size>::table[1] & TTMATH_UINT_HIGHEST_BIT) == 0) ? 0 : 1;
stevep 0:04a9f72bbca7 898
stevep 0:04a9f72bbca7 899 return 0;
stevep 0:04a9f72bbca7 900 }
stevep 0:04a9f72bbca7 901
stevep 0:04a9f72bbca7 902
stevep 0:04a9f72bbca7 903 /*!
stevep 0:04a9f72bbca7 904 this method converts unsigned 64 bit int type to this class
stevep 0:04a9f72bbca7 905 ***this method is created only on a 32bit platform***
stevep 0:04a9f72bbca7 906 */
stevep 0:04a9f72bbca7 907 uint FromInt(ulint n)
stevep 0:04a9f72bbca7 908 {
stevep 0:04a9f72bbca7 909 return FromUInt(n);
stevep 0:04a9f72bbca7 910 }
stevep 0:04a9f72bbca7 911
stevep 0:04a9f72bbca7 912
stevep 0:04a9f72bbca7 913 /*!
stevep 0:04a9f72bbca7 914 this method converts signed 64 bit int type to this class
stevep 0:04a9f72bbca7 915 ***this method is created only on a 32bit platform***
stevep 0:04a9f72bbca7 916 */
stevep 0:04a9f72bbca7 917 uint FromInt(slint n)
stevep 0:04a9f72bbca7 918 {
stevep 0:04a9f72bbca7 919 uint mask = (n < 0) ? TTMATH_UINT_MAX_VALUE : 0;
stevep 0:04a9f72bbca7 920
stevep 0:04a9f72bbca7 921 UInt<value_size>::table[0] = (uint)(ulint)n;
stevep 0:04a9f72bbca7 922
stevep 0:04a9f72bbca7 923 if( value_size == 1 )
stevep 0:04a9f72bbca7 924 {
stevep 0:04a9f72bbca7 925 if( uint(ulint(n) >> 32) != mask )
stevep 0:04a9f72bbca7 926 return 1;
stevep 0:04a9f72bbca7 927
stevep 0:04a9f72bbca7 928 return ((UInt<value_size>::table[0] & TTMATH_UINT_HIGHEST_BIT) == (mask & TTMATH_UINT_HIGHEST_BIT)) ? 0 : 1;
stevep 0:04a9f72bbca7 929 }
stevep 0:04a9f72bbca7 930
stevep 0:04a9f72bbca7 931 UInt<value_size>::table[1] = (uint)(ulint(n) >> 32);
stevep 0:04a9f72bbca7 932
stevep 0:04a9f72bbca7 933 for(uint i=2 ; i<value_size ; ++i)
stevep 0:04a9f72bbca7 934 UInt<value_size>::table[i] = mask;
stevep 0:04a9f72bbca7 935
stevep 0:04a9f72bbca7 936 return 0;
stevep 0:04a9f72bbca7 937 }
stevep 0:04a9f72bbca7 938
stevep 0:04a9f72bbca7 939
stevep 0:04a9f72bbca7 940 /*!
stevep 0:04a9f72bbca7 941 this operator converts unsigned 64 bit int type to this class
stevep 0:04a9f72bbca7 942 ***this operator is created only on a 32bit platform***
stevep 0:04a9f72bbca7 943 */
stevep 0:04a9f72bbca7 944 Int<value_size> & operator=(ulint n)
stevep 0:04a9f72bbca7 945 {
stevep 0:04a9f72bbca7 946 FromUInt(n);
stevep 0:04a9f72bbca7 947
stevep 0:04a9f72bbca7 948 return *this;
stevep 0:04a9f72bbca7 949 }
stevep 0:04a9f72bbca7 950
stevep 0:04a9f72bbca7 951
stevep 0:04a9f72bbca7 952 /*!
stevep 0:04a9f72bbca7 953 a constructor for converting unsigned 64 bit int to this class
stevep 0:04a9f72bbca7 954 ***this constructor is created only on a 32bit platform***
stevep 0:04a9f72bbca7 955 */
stevep 0:04a9f72bbca7 956 Int(ulint n)
stevep 0:04a9f72bbca7 957 {
stevep 0:04a9f72bbca7 958 FromUInt(n);
stevep 0:04a9f72bbca7 959 }
stevep 0:04a9f72bbca7 960
stevep 0:04a9f72bbca7 961
stevep 0:04a9f72bbca7 962 /*!
stevep 0:04a9f72bbca7 963 this operator converts signed 64 bit int type to this class
stevep 0:04a9f72bbca7 964 ***this operator is created only on a 32bit platform***
stevep 0:04a9f72bbca7 965 */
stevep 0:04a9f72bbca7 966 Int<value_size> & operator=(slint n)
stevep 0:04a9f72bbca7 967 {
stevep 0:04a9f72bbca7 968 FromInt(n);
stevep 0:04a9f72bbca7 969
stevep 0:04a9f72bbca7 970 return *this;
stevep 0:04a9f72bbca7 971 }
stevep 0:04a9f72bbca7 972
stevep 0:04a9f72bbca7 973
stevep 0:04a9f72bbca7 974 /*!
stevep 0:04a9f72bbca7 975 a constructor for converting signed 64 bit int to this class
stevep 0:04a9f72bbca7 976 ***this constructor is created only on a 32bit platform***
stevep 0:04a9f72bbca7 977 */
stevep 0:04a9f72bbca7 978 Int(slint n)
stevep 0:04a9f72bbca7 979 {
stevep 0:04a9f72bbca7 980 FromInt(n);
stevep 0:04a9f72bbca7 981 }
stevep 0:04a9f72bbca7 982
stevep 0:04a9f72bbca7 983 #endif
stevep 0:04a9f72bbca7 984
stevep 0:04a9f72bbca7 985
stevep 0:04a9f72bbca7 986
stevep 0:04a9f72bbca7 987
stevep 0:04a9f72bbca7 988 #ifdef TTMATH_PLATFORM64
stevep 0:04a9f72bbca7 989
stevep 0:04a9f72bbca7 990 /*!
stevep 0:04a9f72bbca7 991 this method converts 32 bit unsigned int type to this class
stevep 0:04a9f72bbca7 992 ***this operator is created only on a 64bit platform***
stevep 0:04a9f72bbca7 993 */
stevep 0:04a9f72bbca7 994 uint FromUInt(unsigned int i)
stevep 0:04a9f72bbca7 995 {
stevep 0:04a9f72bbca7 996 return FromUInt(uint(i));
stevep 0:04a9f72bbca7 997 }
stevep 0:04a9f72bbca7 998
stevep 0:04a9f72bbca7 999
stevep 0:04a9f72bbca7 1000 /*!
stevep 0:04a9f72bbca7 1001 this method converts 32 bit unsigned int type to this class
stevep 0:04a9f72bbca7 1002 ***this operator is created only on a 64bit platform***
stevep 0:04a9f72bbca7 1003 */
stevep 0:04a9f72bbca7 1004 uint FromInt(unsigned int i)
stevep 0:04a9f72bbca7 1005 {
stevep 0:04a9f72bbca7 1006 return FromUInt(i);
stevep 0:04a9f72bbca7 1007 }
stevep 0:04a9f72bbca7 1008
stevep 0:04a9f72bbca7 1009
stevep 0:04a9f72bbca7 1010 /*!
stevep 0:04a9f72bbca7 1011 this method converts 32 bit signed int type to this class
stevep 0:04a9f72bbca7 1012 ***this operator is created only on a 64bit platform***
stevep 0:04a9f72bbca7 1013 */
stevep 0:04a9f72bbca7 1014 uint FromInt(signed int i)
stevep 0:04a9f72bbca7 1015 {
stevep 0:04a9f72bbca7 1016 return FromInt(sint(i));
stevep 0:04a9f72bbca7 1017 }
stevep 0:04a9f72bbca7 1018
stevep 0:04a9f72bbca7 1019
stevep 0:04a9f72bbca7 1020 /*!
stevep 0:04a9f72bbca7 1021 this method converts 32 bit unsigned int type to this class
stevep 0:04a9f72bbca7 1022 ***this operator is created only on a 64bit platform***
stevep 0:04a9f72bbca7 1023 */
stevep 0:04a9f72bbca7 1024 Int<value_size> & operator=(unsigned int i)
stevep 0:04a9f72bbca7 1025 {
stevep 0:04a9f72bbca7 1026 FromUInt(i);
stevep 0:04a9f72bbca7 1027
stevep 0:04a9f72bbca7 1028 return *this;
stevep 0:04a9f72bbca7 1029 }
stevep 0:04a9f72bbca7 1030
stevep 0:04a9f72bbca7 1031
stevep 0:04a9f72bbca7 1032 /*!
stevep 0:04a9f72bbca7 1033 a constructor for converting 32 bit unsigned int to this class
stevep 0:04a9f72bbca7 1034 ***this constructor is created only on a 64bit platform***
stevep 0:04a9f72bbca7 1035 */
stevep 0:04a9f72bbca7 1036 Int(unsigned int i)
stevep 0:04a9f72bbca7 1037 {
stevep 0:04a9f72bbca7 1038 FromUInt(i);
stevep 0:04a9f72bbca7 1039 }
stevep 0:04a9f72bbca7 1040
stevep 0:04a9f72bbca7 1041
stevep 0:04a9f72bbca7 1042 /*!
stevep 0:04a9f72bbca7 1043 this operator converts 32 bit signed int type to this class
stevep 0:04a9f72bbca7 1044 ***this operator is created only on a 64bit platform***
stevep 0:04a9f72bbca7 1045 */
stevep 0:04a9f72bbca7 1046 Int<value_size> & operator=(signed int i)
stevep 0:04a9f72bbca7 1047 {
stevep 0:04a9f72bbca7 1048 FromInt(i);
stevep 0:04a9f72bbca7 1049
stevep 0:04a9f72bbca7 1050 return *this;
stevep 0:04a9f72bbca7 1051 }
stevep 0:04a9f72bbca7 1052
stevep 0:04a9f72bbca7 1053
stevep 0:04a9f72bbca7 1054 /*!
stevep 0:04a9f72bbca7 1055 a constructor for converting 32 bit signed int to this class
stevep 0:04a9f72bbca7 1056 ***this constructor is created only on a 64bit platform***
stevep 0:04a9f72bbca7 1057 */
stevep 0:04a9f72bbca7 1058 Int(signed int i)
stevep 0:04a9f72bbca7 1059 {
stevep 0:04a9f72bbca7 1060 FromInt(i);
stevep 0:04a9f72bbca7 1061 }
stevep 0:04a9f72bbca7 1062
stevep 0:04a9f72bbca7 1063 #endif
stevep 0:04a9f72bbca7 1064
stevep 0:04a9f72bbca7 1065
stevep 0:04a9f72bbca7 1066
stevep 0:04a9f72bbca7 1067 /*!
stevep 0:04a9f72bbca7 1068 a constructor for converting string to this class (with the base=10)
stevep 0:04a9f72bbca7 1069 */
stevep 0:04a9f72bbca7 1070 Int(const char * s)
stevep 0:04a9f72bbca7 1071 {
stevep 0:04a9f72bbca7 1072 FromString(s);
stevep 0:04a9f72bbca7 1073 }
stevep 0:04a9f72bbca7 1074
stevep 0:04a9f72bbca7 1075
stevep 0:04a9f72bbca7 1076 /*!
stevep 0:04a9f72bbca7 1077 a constructor for converting a string to this class (with the base=10)
stevep 0:04a9f72bbca7 1078 */
stevep 0:04a9f72bbca7 1079 Int(const std::string & s)
stevep 0:04a9f72bbca7 1080 {
stevep 0:04a9f72bbca7 1081 FromString( s.c_str() );
stevep 0:04a9f72bbca7 1082 }
stevep 0:04a9f72bbca7 1083
stevep 0:04a9f72bbca7 1084
stevep 0:04a9f72bbca7 1085 #ifndef TTMATH_DONT_USE_WCHAR
stevep 0:04a9f72bbca7 1086
stevep 0:04a9f72bbca7 1087 /*!
stevep 0:04a9f72bbca7 1088 a constructor for converting string to this class (with the base=10)
stevep 0:04a9f72bbca7 1089 */
stevep 0:04a9f72bbca7 1090 Int(const wchar_t * s)
stevep 0:04a9f72bbca7 1091 {
stevep 0:04a9f72bbca7 1092 FromString(s);
stevep 0:04a9f72bbca7 1093 }
stevep 0:04a9f72bbca7 1094
stevep 0:04a9f72bbca7 1095
stevep 0:04a9f72bbca7 1096 /*!
stevep 0:04a9f72bbca7 1097 a constructor for converting a string to this class (with the base=10)
stevep 0:04a9f72bbca7 1098 */
stevep 0:04a9f72bbca7 1099 Int(const std::wstring & s)
stevep 0:04a9f72bbca7 1100 {
stevep 0:04a9f72bbca7 1101 FromString( s.c_str() );
stevep 0:04a9f72bbca7 1102 }
stevep 0:04a9f72bbca7 1103
stevep 0:04a9f72bbca7 1104 #endif
stevep 0:04a9f72bbca7 1105
stevep 0:04a9f72bbca7 1106
stevep 0:04a9f72bbca7 1107 /*!
stevep 0:04a9f72bbca7 1108 a default constructor
stevep 0:04a9f72bbca7 1109
stevep 0:04a9f72bbca7 1110 we don't clear table etc.
stevep 0:04a9f72bbca7 1111 */
stevep 0:04a9f72bbca7 1112 Int()
stevep 0:04a9f72bbca7 1113 {
stevep 0:04a9f72bbca7 1114 }
stevep 0:04a9f72bbca7 1115
stevep 0:04a9f72bbca7 1116
stevep 0:04a9f72bbca7 1117 /*!
stevep 0:04a9f72bbca7 1118 the destructor
stevep 0:04a9f72bbca7 1119 */
stevep 0:04a9f72bbca7 1120 ~Int()
stevep 0:04a9f72bbca7 1121 {
stevep 0:04a9f72bbca7 1122 }
stevep 0:04a9f72bbca7 1123
stevep 0:04a9f72bbca7 1124
stevep 0:04a9f72bbca7 1125 /*!
stevep 0:04a9f72bbca7 1126 this method returns the lowest value from table with a sign
stevep 0:04a9f72bbca7 1127
stevep 0:04a9f72bbca7 1128 we must be sure when we using this method whether the value
stevep 0:04a9f72bbca7 1129 will hold in an sint type or not (the rest value from table must be zero or -1)
stevep 0:04a9f72bbca7 1130 */
stevep 0:04a9f72bbca7 1131 sint ToInt() const
stevep 0:04a9f72bbca7 1132 {
stevep 0:04a9f72bbca7 1133 return sint( UInt<value_size>::table[0] );
stevep 0:04a9f72bbca7 1134 }
stevep 0:04a9f72bbca7 1135
stevep 0:04a9f72bbca7 1136
stevep 0:04a9f72bbca7 1137 /*!
stevep 0:04a9f72bbca7 1138 this method converts the value to uint type
stevep 0:04a9f72bbca7 1139 can return a carry if the value is too long to store it in uint type
stevep 0:04a9f72bbca7 1140 */
stevep 0:04a9f72bbca7 1141 uint ToUInt(uint & result) const
stevep 0:04a9f72bbca7 1142 {
stevep 0:04a9f72bbca7 1143 uint c = UInt<value_size>::ToUInt(result);
stevep 0:04a9f72bbca7 1144
stevep 0:04a9f72bbca7 1145 if( value_size == 1 )
stevep 0:04a9f72bbca7 1146 return (result & TTMATH_UINT_HIGHEST_BIT) == 0 ? 0 : 1;
stevep 0:04a9f72bbca7 1147
stevep 0:04a9f72bbca7 1148 return c;
stevep 0:04a9f72bbca7 1149 }
stevep 0:04a9f72bbca7 1150
stevep 0:04a9f72bbca7 1151
stevep 0:04a9f72bbca7 1152 /*!
stevep 0:04a9f72bbca7 1153 this method converts the value to uint type
stevep 0:04a9f72bbca7 1154 can return a carry if the value is too long to store it in uint type
stevep 0:04a9f72bbca7 1155 */
stevep 0:04a9f72bbca7 1156 uint ToInt(uint & result) const
stevep 0:04a9f72bbca7 1157 {
stevep 0:04a9f72bbca7 1158 return ToUInt(result);
stevep 0:04a9f72bbca7 1159 }
stevep 0:04a9f72bbca7 1160
stevep 0:04a9f72bbca7 1161
stevep 0:04a9f72bbca7 1162 /*!
stevep 0:04a9f72bbca7 1163 this method converts the value to sint type
stevep 0:04a9f72bbca7 1164 can return a carry if the value is too long to store it in sint type
stevep 0:04a9f72bbca7 1165 */
stevep 0:04a9f72bbca7 1166 uint ToInt(sint & result) const
stevep 0:04a9f72bbca7 1167 {
stevep 0:04a9f72bbca7 1168 result = sint( UInt<value_size>::table[0] );
stevep 0:04a9f72bbca7 1169 uint mask = IsSign() ? TTMATH_UINT_MAX_VALUE : 0;
stevep 0:04a9f72bbca7 1170
stevep 0:04a9f72bbca7 1171 if( (result & TTMATH_UINT_HIGHEST_BIT) != (mask & TTMATH_UINT_HIGHEST_BIT) )
stevep 0:04a9f72bbca7 1172 return 1;
stevep 0:04a9f72bbca7 1173
stevep 0:04a9f72bbca7 1174 for(uint i=1 ; i<value_size ; ++i)
stevep 0:04a9f72bbca7 1175 if( UInt<value_size>::table[i] != mask )
stevep 0:04a9f72bbca7 1176 return 1;
stevep 0:04a9f72bbca7 1177
stevep 0:04a9f72bbca7 1178 return 0;
stevep 0:04a9f72bbca7 1179 }
stevep 0:04a9f72bbca7 1180
stevep 0:04a9f72bbca7 1181
stevep 0:04a9f72bbca7 1182 #ifdef TTMATH_PLATFORM32
stevep 0:04a9f72bbca7 1183
stevep 0:04a9f72bbca7 1184 /*!
stevep 0:04a9f72bbca7 1185 this method converts the value to ulint type (64 bit unsigned integer)
stevep 0:04a9f72bbca7 1186 can return a carry if the value is too long to store it in ulint type
stevep 0:04a9f72bbca7 1187 *** this method is created only on a 32 bit platform ***
stevep 0:04a9f72bbca7 1188 */
stevep 0:04a9f72bbca7 1189 uint ToUInt(ulint & result) const
stevep 0:04a9f72bbca7 1190 {
stevep 0:04a9f72bbca7 1191 uint c = UInt<value_size>::ToUInt(result);
stevep 0:04a9f72bbca7 1192
stevep 0:04a9f72bbca7 1193 if( value_size == 1 )
stevep 0:04a9f72bbca7 1194 return (UInt<value_size>::table[0] & TTMATH_UINT_HIGHEST_BIT) == 0 ? 0 : 1;
stevep 0:04a9f72bbca7 1195
stevep 0:04a9f72bbca7 1196 if( value_size == 2 )
stevep 0:04a9f72bbca7 1197 return (UInt<value_size>::table[1] & TTMATH_UINT_HIGHEST_BIT) == 0 ? 0 : 1;
stevep 0:04a9f72bbca7 1198
stevep 0:04a9f72bbca7 1199 return c;
stevep 0:04a9f72bbca7 1200 }
stevep 0:04a9f72bbca7 1201
stevep 0:04a9f72bbca7 1202
stevep 0:04a9f72bbca7 1203 /*!
stevep 0:04a9f72bbca7 1204 this method converts the value to ulint type (64 bit unsigned integer)
stevep 0:04a9f72bbca7 1205 can return a carry if the value is too long to store it in ulint type
stevep 0:04a9f72bbca7 1206 *** this method is created only on a 32 bit platform ***
stevep 0:04a9f72bbca7 1207 */
stevep 0:04a9f72bbca7 1208 uint ToInt(ulint & result) const
stevep 0:04a9f72bbca7 1209 {
stevep 0:04a9f72bbca7 1210 return ToUInt(result);
stevep 0:04a9f72bbca7 1211 }
stevep 0:04a9f72bbca7 1212
stevep 0:04a9f72bbca7 1213
stevep 0:04a9f72bbca7 1214 /*!
stevep 0:04a9f72bbca7 1215 this method converts the value to slint type (64 bit signed integer)
stevep 0:04a9f72bbca7 1216 can return a carry if the value is too long to store it in slint type
stevep 0:04a9f72bbca7 1217 *** this method is created only on a 32 bit platform ***
stevep 0:04a9f72bbca7 1218 */
stevep 0:04a9f72bbca7 1219 uint ToInt(slint & result) const
stevep 0:04a9f72bbca7 1220 {
stevep 0:04a9f72bbca7 1221 if( value_size == 1 )
stevep 0:04a9f72bbca7 1222 {
stevep 0:04a9f72bbca7 1223 result = slint(sint(UInt<value_size>::table[0]));
stevep 0:04a9f72bbca7 1224 }
stevep 0:04a9f72bbca7 1225 else
stevep 0:04a9f72bbca7 1226 {
stevep 0:04a9f72bbca7 1227 uint low = UInt<value_size>::table[0];
stevep 0:04a9f72bbca7 1228 uint high = UInt<value_size>::table[1];
stevep 0:04a9f72bbca7 1229
stevep 0:04a9f72bbca7 1230 result = low;
stevep 0:04a9f72bbca7 1231 result |= (ulint(high) << TTMATH_BITS_PER_UINT);
stevep 0:04a9f72bbca7 1232
stevep 0:04a9f72bbca7 1233 uint mask = IsSign() ? TTMATH_UINT_MAX_VALUE : 0;
stevep 0:04a9f72bbca7 1234
stevep 0:04a9f72bbca7 1235 if( (high & TTMATH_UINT_HIGHEST_BIT) != (mask & TTMATH_UINT_HIGHEST_BIT) )
stevep 0:04a9f72bbca7 1236 return 1;
stevep 0:04a9f72bbca7 1237
stevep 0:04a9f72bbca7 1238 for(uint i=2 ; i<value_size ; ++i)
stevep 0:04a9f72bbca7 1239 if( UInt<value_size>::table[i] != mask )
stevep 0:04a9f72bbca7 1240 return 1;
stevep 0:04a9f72bbca7 1241 }
stevep 0:04a9f72bbca7 1242
stevep 0:04a9f72bbca7 1243 return 0;
stevep 0:04a9f72bbca7 1244 }
stevep 0:04a9f72bbca7 1245
stevep 0:04a9f72bbca7 1246 #endif
stevep 0:04a9f72bbca7 1247
stevep 0:04a9f72bbca7 1248
stevep 0:04a9f72bbca7 1249
stevep 0:04a9f72bbca7 1250 #ifdef TTMATH_PLATFORM64
stevep 0:04a9f72bbca7 1251
stevep 0:04a9f72bbca7 1252 /*!
stevep 0:04a9f72bbca7 1253 this method converts the value to a 32 bit unsigned integer
stevep 0:04a9f72bbca7 1254 can return a carry if the value is too long to store it in this type
stevep 0:04a9f72bbca7 1255 *** this method is created only on a 64 bit platform ***
stevep 0:04a9f72bbca7 1256 */
stevep 0:04a9f72bbca7 1257 uint ToUInt(unsigned int & result) const
stevep 0:04a9f72bbca7 1258 {
stevep 0:04a9f72bbca7 1259 uint c = UInt<value_size>::ToUInt(result);
stevep 0:04a9f72bbca7 1260
stevep 0:04a9f72bbca7 1261 if( c || IsSign() )
stevep 0:04a9f72bbca7 1262 return 1;
stevep 0:04a9f72bbca7 1263
stevep 0:04a9f72bbca7 1264 return 0;
stevep 0:04a9f72bbca7 1265 }
stevep 0:04a9f72bbca7 1266
stevep 0:04a9f72bbca7 1267
stevep 0:04a9f72bbca7 1268 /*!
stevep 0:04a9f72bbca7 1269 this method converts the value to a 32 bit unsigned integer
stevep 0:04a9f72bbca7 1270 can return a carry if the value is too long to store it in this type
stevep 0:04a9f72bbca7 1271 *** this method is created only on a 64 bit platform ***
stevep 0:04a9f72bbca7 1272 */
stevep 0:04a9f72bbca7 1273 uint ToInt(unsigned int & result) const
stevep 0:04a9f72bbca7 1274 {
stevep 0:04a9f72bbca7 1275 return ToUInt(result);
stevep 0:04a9f72bbca7 1276 }
stevep 0:04a9f72bbca7 1277
stevep 0:04a9f72bbca7 1278
stevep 0:04a9f72bbca7 1279 /*!
stevep 0:04a9f72bbca7 1280 this method converts the value to a 32 bit signed integer
stevep 0:04a9f72bbca7 1281 can return a carry if the value is too long to store it in this type
stevep 0:04a9f72bbca7 1282 *** this method is created only on a 64 bit platform ***
stevep 0:04a9f72bbca7 1283 */
stevep 0:04a9f72bbca7 1284 uint ToInt(int & result) const
stevep 0:04a9f72bbca7 1285 {
stevep 0:04a9f72bbca7 1286 uint first = UInt<value_size>::table[0];
stevep 0:04a9f72bbca7 1287
stevep 0:04a9f72bbca7 1288 result = int(first);
stevep 0:04a9f72bbca7 1289 uint mask = IsSign() ? TTMATH_UINT_MAX_VALUE : 0;
stevep 0:04a9f72bbca7 1290
stevep 0:04a9f72bbca7 1291 if( (first >> 31) != (mask >> 31) )
stevep 0:04a9f72bbca7 1292 return 1;
stevep 0:04a9f72bbca7 1293
stevep 0:04a9f72bbca7 1294 for(uint i=1 ; i<value_size ; ++i)
stevep 0:04a9f72bbca7 1295 if( UInt<value_size>::table[i] != mask )
stevep 0:04a9f72bbca7 1296 return 1;
stevep 0:04a9f72bbca7 1297
stevep 0:04a9f72bbca7 1298 return 0;
stevep 0:04a9f72bbca7 1299 }
stevep 0:04a9f72bbca7 1300
stevep 0:04a9f72bbca7 1301 #endif
stevep 0:04a9f72bbca7 1302
stevep 0:04a9f72bbca7 1303
stevep 0:04a9f72bbca7 1304
stevep 0:04a9f72bbca7 1305
stevep 0:04a9f72bbca7 1306 private:
stevep 0:04a9f72bbca7 1307
stevep 0:04a9f72bbca7 1308 /*!
stevep 0:04a9f72bbca7 1309 an auxiliary method for converting to a string
stevep 0:04a9f72bbca7 1310 */
stevep 0:04a9f72bbca7 1311 template<class string_type>
stevep 0:04a9f72bbca7 1312 void ToStringBase(string_type & result, uint b = 10) const
stevep 0:04a9f72bbca7 1313 {
stevep 0:04a9f72bbca7 1314 if( IsSign() )
stevep 0:04a9f72bbca7 1315 {
stevep 0:04a9f72bbca7 1316 Int<value_size> temp(*this);
stevep 0:04a9f72bbca7 1317 temp.Abs();
stevep 0:04a9f72bbca7 1318 temp.UInt<value_size>::ToStringBase(result, b, true);
stevep 0:04a9f72bbca7 1319 }
stevep 0:04a9f72bbca7 1320 else
stevep 0:04a9f72bbca7 1321 {
stevep 0:04a9f72bbca7 1322 UInt<value_size>::ToStringBase(result, b, false);
stevep 0:04a9f72bbca7 1323 }
stevep 0:04a9f72bbca7 1324 }
stevep 0:04a9f72bbca7 1325
stevep 0:04a9f72bbca7 1326 public:
stevep 0:04a9f72bbca7 1327
stevep 0:04a9f72bbca7 1328 /*!
stevep 0:04a9f72bbca7 1329 this method converts the value to a string with a base equal 'b'
stevep 0:04a9f72bbca7 1330 */
stevep 0:04a9f72bbca7 1331 void ToString(std::string & result, uint b = 10) const
stevep 0:04a9f72bbca7 1332 {
stevep 0:04a9f72bbca7 1333 return ToStringBase(result, b);
stevep 0:04a9f72bbca7 1334 }
stevep 0:04a9f72bbca7 1335
stevep 0:04a9f72bbca7 1336
stevep 0:04a9f72bbca7 1337 /*!
stevep 0:04a9f72bbca7 1338 this method converts the value to a string with a base equal 'b'
stevep 0:04a9f72bbca7 1339 */
stevep 0:04a9f72bbca7 1340 std::string ToString(uint b = 10) const
stevep 0:04a9f72bbca7 1341 {
stevep 0:04a9f72bbca7 1342 std::string result;
stevep 0:04a9f72bbca7 1343 ToStringBase(result, b);
stevep 0:04a9f72bbca7 1344
stevep 0:04a9f72bbca7 1345 return result;
stevep 0:04a9f72bbca7 1346 }
stevep 0:04a9f72bbca7 1347
stevep 0:04a9f72bbca7 1348
stevep 0:04a9f72bbca7 1349 #ifndef TTMATH_DONT_USE_WCHAR
stevep 0:04a9f72bbca7 1350
stevep 0:04a9f72bbca7 1351 /*!
stevep 0:04a9f72bbca7 1352 this method converts the value to a string with a base equal 'b'
stevep 0:04a9f72bbca7 1353 */
stevep 0:04a9f72bbca7 1354 void ToString(std::wstring & result, uint b = 10) const
stevep 0:04a9f72bbca7 1355 {
stevep 0:04a9f72bbca7 1356 return ToStringBase(result, b);
stevep 0:04a9f72bbca7 1357 }
stevep 0:04a9f72bbca7 1358
stevep 0:04a9f72bbca7 1359
stevep 0:04a9f72bbca7 1360 /*!
stevep 0:04a9f72bbca7 1361 this method converts the value to a string with a base equal 'b'
stevep 0:04a9f72bbca7 1362 */
stevep 0:04a9f72bbca7 1363 std::wstring ToWString(uint b = 10) const
stevep 0:04a9f72bbca7 1364 {
stevep 0:04a9f72bbca7 1365 std::wstring result;
stevep 0:04a9f72bbca7 1366 ToStringBase(result, b);
stevep 0:04a9f72bbca7 1367
stevep 0:04a9f72bbca7 1368 return result;
stevep 0:04a9f72bbca7 1369 }
stevep 0:04a9f72bbca7 1370
stevep 0:04a9f72bbca7 1371 #endif
stevep 0:04a9f72bbca7 1372
stevep 0:04a9f72bbca7 1373
stevep 0:04a9f72bbca7 1374
stevep 0:04a9f72bbca7 1375 private:
stevep 0:04a9f72bbca7 1376
stevep 0:04a9f72bbca7 1377 /*!
stevep 0:04a9f72bbca7 1378 an auxiliary method for converting from a string
stevep 0:04a9f72bbca7 1379 */
stevep 0:04a9f72bbca7 1380 template<class char_type>
stevep 0:04a9f72bbca7 1381 uint FromStringBase(const char_type * s, uint b = 10, const char_type ** after_source = 0, bool * value_read = 0)
stevep 0:04a9f72bbca7 1382 {
stevep 0:04a9f72bbca7 1383 bool is_sign = false;
stevep 0:04a9f72bbca7 1384
stevep 0:04a9f72bbca7 1385 Misc::SkipWhiteCharacters(s);
stevep 0:04a9f72bbca7 1386
stevep 0:04a9f72bbca7 1387 if( *s == '-' )
stevep 0:04a9f72bbca7 1388 {
stevep 0:04a9f72bbca7 1389 is_sign = true;
stevep 0:04a9f72bbca7 1390 Misc::SkipWhiteCharacters(++s);
stevep 0:04a9f72bbca7 1391 }
stevep 0:04a9f72bbca7 1392 else
stevep 0:04a9f72bbca7 1393 if( *s == '+' )
stevep 0:04a9f72bbca7 1394 {
stevep 0:04a9f72bbca7 1395 Misc::SkipWhiteCharacters(++s);
stevep 0:04a9f72bbca7 1396 }
stevep 0:04a9f72bbca7 1397
stevep 0:04a9f72bbca7 1398 if( UInt<value_size>::FromString(s,b,after_source,value_read) )
stevep 0:04a9f72bbca7 1399 return 1;
stevep 0:04a9f72bbca7 1400
stevep 0:04a9f72bbca7 1401 if( is_sign )
stevep 0:04a9f72bbca7 1402 {
stevep 0:04a9f72bbca7 1403 Int<value_size> mmin;
stevep 0:04a9f72bbca7 1404
stevep 0:04a9f72bbca7 1405 mmin.SetMin();
stevep 0:04a9f72bbca7 1406
stevep 0:04a9f72bbca7 1407 /*
stevep 0:04a9f72bbca7 1408 the reference to mmin will be automatically converted to the reference
stevep 0:04a9f72bbca7 1409 to UInt type
stevep 0:04a9f72bbca7 1410 (this value can be equal mmin -- look at a description in ChangeSign())
stevep 0:04a9f72bbca7 1411 */
stevep 0:04a9f72bbca7 1412 if( UInt<value_size>::operator>( mmin ) )
stevep 0:04a9f72bbca7 1413 return 1;
stevep 0:04a9f72bbca7 1414
stevep 0:04a9f72bbca7 1415 /*
stevep 0:04a9f72bbca7 1416 if the value is equal mmin the method ChangeSign() does nothing (only returns 1 but we ignore it)
stevep 0:04a9f72bbca7 1417 */
stevep 0:04a9f72bbca7 1418 ChangeSign();
stevep 0:04a9f72bbca7 1419 }
stevep 0:04a9f72bbca7 1420 else
stevep 0:04a9f72bbca7 1421 {
stevep 0:04a9f72bbca7 1422 Int<value_size> mmax;
stevep 0:04a9f72bbca7 1423
stevep 0:04a9f72bbca7 1424 mmax.SetMax();
stevep 0:04a9f72bbca7 1425
stevep 0:04a9f72bbca7 1426 if( UInt<value_size>::operator>( mmax ) )
stevep 0:04a9f72bbca7 1427 return 1;
stevep 0:04a9f72bbca7 1428 }
stevep 0:04a9f72bbca7 1429
stevep 0:04a9f72bbca7 1430 return 0;
stevep 0:04a9f72bbca7 1431 }
stevep 0:04a9f72bbca7 1432
stevep 0:04a9f72bbca7 1433
stevep 0:04a9f72bbca7 1434 public:
stevep 0:04a9f72bbca7 1435
stevep 0:04a9f72bbca7 1436 /*!
stevep 0:04a9f72bbca7 1437 this method converts a string into its value
stevep 0:04a9f72bbca7 1438 it returns carry=1 if the value will be too big or an incorrect base 'b' is given
stevep 0:04a9f72bbca7 1439
stevep 0:04a9f72bbca7 1440 string is ended with a non-digit value, for example:
stevep 0:04a9f72bbca7 1441 "-12" will be translated to -12
stevep 0:04a9f72bbca7 1442 as well as:
stevep 0:04a9f72bbca7 1443 "- 12foo" will be translated to -12 too
stevep 0:04a9f72bbca7 1444
stevep 0:04a9f72bbca7 1445 existing first white characters will be ommited
stevep 0:04a9f72bbca7 1446 (between '-' and a first digit can be white characters too)
stevep 0:04a9f72bbca7 1447
stevep 0:04a9f72bbca7 1448 after_source (if exists) is pointing at the end of the parsed string
stevep 0:04a9f72bbca7 1449
stevep 0:04a9f72bbca7 1450 value_read (if exists) tells whether something has actually been read (at least one digit)
stevep 0:04a9f72bbca7 1451 */
stevep 0:04a9f72bbca7 1452 uint FromString(const char * s, uint b = 10, const char ** after_source = 0, bool * value_read = 0)
stevep 0:04a9f72bbca7 1453 {
stevep 0:04a9f72bbca7 1454 return FromStringBase(s, b, after_source, value_read);
stevep 0:04a9f72bbca7 1455 }
stevep 0:04a9f72bbca7 1456
stevep 0:04a9f72bbca7 1457
stevep 0:04a9f72bbca7 1458 /*!
stevep 0:04a9f72bbca7 1459 this method converts a string into its value
stevep 0:04a9f72bbca7 1460 */
stevep 0:04a9f72bbca7 1461 uint FromString(const wchar_t * s, uint b = 10, const wchar_t ** after_source = 0, bool * value_read = 0)
stevep 0:04a9f72bbca7 1462 {
stevep 0:04a9f72bbca7 1463 return FromStringBase(s, b, after_source, value_read);
stevep 0:04a9f72bbca7 1464 }
stevep 0:04a9f72bbca7 1465
stevep 0:04a9f72bbca7 1466
stevep 0:04a9f72bbca7 1467 /*!
stevep 0:04a9f72bbca7 1468 this method converts a string into its value
stevep 0:04a9f72bbca7 1469 it returns carry=1 if the value will be too big or an incorrect base 'b' is given
stevep 0:04a9f72bbca7 1470 */
stevep 0:04a9f72bbca7 1471 uint FromString(const std::string & s, uint b = 10)
stevep 0:04a9f72bbca7 1472 {
stevep 0:04a9f72bbca7 1473 return FromString( s.c_str(), b );
stevep 0:04a9f72bbca7 1474 }
stevep 0:04a9f72bbca7 1475
stevep 0:04a9f72bbca7 1476
stevep 0:04a9f72bbca7 1477 /*!
stevep 0:04a9f72bbca7 1478 this operator converts a string into its value (with base = 10)
stevep 0:04a9f72bbca7 1479 */
stevep 0:04a9f72bbca7 1480 Int<value_size> & operator=(const char * s)
stevep 0:04a9f72bbca7 1481 {
stevep 0:04a9f72bbca7 1482 FromString(s);
stevep 0:04a9f72bbca7 1483
stevep 0:04a9f72bbca7 1484 return *this;
stevep 0:04a9f72bbca7 1485 }
stevep 0:04a9f72bbca7 1486
stevep 0:04a9f72bbca7 1487
stevep 0:04a9f72bbca7 1488 #ifndef TTMATH_DONT_USE_WCHAR
stevep 0:04a9f72bbca7 1489
stevep 0:04a9f72bbca7 1490
stevep 0:04a9f72bbca7 1491 /*!
stevep 0:04a9f72bbca7 1492 this method converts a string into its value
stevep 0:04a9f72bbca7 1493 it returns carry=1 if the value will be too big or an incorrect base 'b' is given
stevep 0:04a9f72bbca7 1494 */
stevep 0:04a9f72bbca7 1495 uint FromString(const std::wstring & s, uint b = 10)
stevep 0:04a9f72bbca7 1496 {
stevep 0:04a9f72bbca7 1497 return FromString( s.c_str(), b );
stevep 0:04a9f72bbca7 1498 }
stevep 0:04a9f72bbca7 1499
stevep 0:04a9f72bbca7 1500
stevep 0:04a9f72bbca7 1501 /*!
stevep 0:04a9f72bbca7 1502 this operator converts a string into its value (with base = 10)
stevep 0:04a9f72bbca7 1503 */
stevep 0:04a9f72bbca7 1504 Int<value_size> & operator=(const wchar_t * s)
stevep 0:04a9f72bbca7 1505 {
stevep 0:04a9f72bbca7 1506 FromString(s);
stevep 0:04a9f72bbca7 1507
stevep 0:04a9f72bbca7 1508 return *this;
stevep 0:04a9f72bbca7 1509 }
stevep 0:04a9f72bbca7 1510
stevep 0:04a9f72bbca7 1511
stevep 0:04a9f72bbca7 1512 /*!
stevep 0:04a9f72bbca7 1513 this operator converts a string into its value (with base = 10)
stevep 0:04a9f72bbca7 1514 */
stevep 0:04a9f72bbca7 1515 Int<value_size> & operator=(const std::wstring & s)
stevep 0:04a9f72bbca7 1516 {
stevep 0:04a9f72bbca7 1517 FromString( s.c_str() );
stevep 0:04a9f72bbca7 1518
stevep 0:04a9f72bbca7 1519 return *this;
stevep 0:04a9f72bbca7 1520 }
stevep 0:04a9f72bbca7 1521
stevep 0:04a9f72bbca7 1522 #endif
stevep 0:04a9f72bbca7 1523
stevep 0:04a9f72bbca7 1524
stevep 0:04a9f72bbca7 1525 /*!
stevep 0:04a9f72bbca7 1526 this operator converts a string into its value (with base = 10)
stevep 0:04a9f72bbca7 1527 */
stevep 0:04a9f72bbca7 1528 Int<value_size> & operator=(const std::string & s)
stevep 0:04a9f72bbca7 1529 {
stevep 0:04a9f72bbca7 1530 FromString( s.c_str() );
stevep 0:04a9f72bbca7 1531
stevep 0:04a9f72bbca7 1532 return *this;
stevep 0:04a9f72bbca7 1533 }
stevep 0:04a9f72bbca7 1534
stevep 0:04a9f72bbca7 1535
stevep 0:04a9f72bbca7 1536
stevep 0:04a9f72bbca7 1537 /*!
stevep 0:04a9f72bbca7 1538 *
stevep 0:04a9f72bbca7 1539 * methods for comparing
stevep 0:04a9f72bbca7 1540 *
stevep 0:04a9f72bbca7 1541 *
stevep 0:04a9f72bbca7 1542 */
stevep 0:04a9f72bbca7 1543
stevep 0:04a9f72bbca7 1544 bool operator==(const Int<value_size> & l) const
stevep 0:04a9f72bbca7 1545 {
stevep 0:04a9f72bbca7 1546 return UInt<value_size>::operator==(l);
stevep 0:04a9f72bbca7 1547 }
stevep 0:04a9f72bbca7 1548
stevep 0:04a9f72bbca7 1549 bool operator!=(const Int<value_size> & l) const
stevep 0:04a9f72bbca7 1550 {
stevep 0:04a9f72bbca7 1551 return UInt<value_size>::operator!=(l);
stevep 0:04a9f72bbca7 1552 }
stevep 0:04a9f72bbca7 1553
stevep 0:04a9f72bbca7 1554 bool operator<(const Int<value_size> & l) const
stevep 0:04a9f72bbca7 1555 {
stevep 0:04a9f72bbca7 1556 sint i=value_size-1;
stevep 0:04a9f72bbca7 1557
stevep 0:04a9f72bbca7 1558 sint a1 = sint(UInt<value_size>::table[i]);
stevep 0:04a9f72bbca7 1559 sint a2 = sint(l.table[i]);
stevep 0:04a9f72bbca7 1560
stevep 0:04a9f72bbca7 1561 if( a1 != a2 )
stevep 0:04a9f72bbca7 1562 return a1 < a2;
stevep 0:04a9f72bbca7 1563
stevep 0:04a9f72bbca7 1564
stevep 0:04a9f72bbca7 1565 for(--i ; i>=0 ; --i)
stevep 0:04a9f72bbca7 1566 {
stevep 0:04a9f72bbca7 1567 if( UInt<value_size>::table[i] != l.table[i] )
stevep 0:04a9f72bbca7 1568 // comparison as unsigned int
stevep 0:04a9f72bbca7 1569 return UInt<value_size>::table[i] < l.table[i];
stevep 0:04a9f72bbca7 1570 }
stevep 0:04a9f72bbca7 1571
stevep 0:04a9f72bbca7 1572 // they're equal
stevep 0:04a9f72bbca7 1573 return false;
stevep 0:04a9f72bbca7 1574 }
stevep 0:04a9f72bbca7 1575
stevep 0:04a9f72bbca7 1576
stevep 0:04a9f72bbca7 1577 bool operator>(const Int<value_size> & l) const
stevep 0:04a9f72bbca7 1578 {
stevep 0:04a9f72bbca7 1579 sint i=value_size-1;
stevep 0:04a9f72bbca7 1580
stevep 0:04a9f72bbca7 1581 sint a1 = sint(UInt<value_size>::table[i]);
stevep 0:04a9f72bbca7 1582 sint a2 = sint(l.table[i]);
stevep 0:04a9f72bbca7 1583
stevep 0:04a9f72bbca7 1584 if( a1 != a2 )
stevep 0:04a9f72bbca7 1585 return a1 > a2;
stevep 0:04a9f72bbca7 1586
stevep 0:04a9f72bbca7 1587
stevep 0:04a9f72bbca7 1588 for(--i ; i>=0 ; --i)
stevep 0:04a9f72bbca7 1589 {
stevep 0:04a9f72bbca7 1590 if( UInt<value_size>::table[i] != l.table[i] )
stevep 0:04a9f72bbca7 1591 // comparison as unsigned int
stevep 0:04a9f72bbca7 1592 return UInt<value_size>::table[i] > l.table[i];
stevep 0:04a9f72bbca7 1593 }
stevep 0:04a9f72bbca7 1594
stevep 0:04a9f72bbca7 1595 // they're equal
stevep 0:04a9f72bbca7 1596 return false;
stevep 0:04a9f72bbca7 1597 }
stevep 0:04a9f72bbca7 1598
stevep 0:04a9f72bbca7 1599
stevep 0:04a9f72bbca7 1600 bool operator<=(const Int<value_size> & l) const
stevep 0:04a9f72bbca7 1601 {
stevep 0:04a9f72bbca7 1602 sint i=value_size-1;
stevep 0:04a9f72bbca7 1603
stevep 0:04a9f72bbca7 1604 sint a1 = sint(UInt<value_size>::table[i]);
stevep 0:04a9f72bbca7 1605 sint a2 = sint(l.table[i]);
stevep 0:04a9f72bbca7 1606
stevep 0:04a9f72bbca7 1607 if( a1 != a2 )
stevep 0:04a9f72bbca7 1608 return a1 < a2;
stevep 0:04a9f72bbca7 1609
stevep 0:04a9f72bbca7 1610
stevep 0:04a9f72bbca7 1611 for(--i ; i>=0 ; --i)
stevep 0:04a9f72bbca7 1612 {
stevep 0:04a9f72bbca7 1613 if( UInt<value_size>::table[i] != l.table[i] )
stevep 0:04a9f72bbca7 1614 // comparison as unsigned int
stevep 0:04a9f72bbca7 1615 return UInt<value_size>::table[i] < l.table[i];
stevep 0:04a9f72bbca7 1616 }
stevep 0:04a9f72bbca7 1617
stevep 0:04a9f72bbca7 1618 // they're equal
stevep 0:04a9f72bbca7 1619 return true;
stevep 0:04a9f72bbca7 1620 }
stevep 0:04a9f72bbca7 1621
stevep 0:04a9f72bbca7 1622
stevep 0:04a9f72bbca7 1623 bool operator>=(const Int<value_size> & l) const
stevep 0:04a9f72bbca7 1624 {
stevep 0:04a9f72bbca7 1625 sint i=value_size-1;
stevep 0:04a9f72bbca7 1626
stevep 0:04a9f72bbca7 1627 sint a1 = sint(UInt<value_size>::table[i]);
stevep 0:04a9f72bbca7 1628 sint a2 = sint(l.table[i]);
stevep 0:04a9f72bbca7 1629
stevep 0:04a9f72bbca7 1630 if( a1 != a2 )
stevep 0:04a9f72bbca7 1631 return a1 > a2;
stevep 0:04a9f72bbca7 1632
stevep 0:04a9f72bbca7 1633
stevep 0:04a9f72bbca7 1634 for(--i ; i>=0 ; --i)
stevep 0:04a9f72bbca7 1635 {
stevep 0:04a9f72bbca7 1636 if( UInt<value_size>::table[i] != l.table[i] )
stevep 0:04a9f72bbca7 1637 // comparison as unsigned int
stevep 0:04a9f72bbca7 1638 return UInt<value_size>::table[i] > l.table[i];
stevep 0:04a9f72bbca7 1639 }
stevep 0:04a9f72bbca7 1640
stevep 0:04a9f72bbca7 1641 // they're equal
stevep 0:04a9f72bbca7 1642 return true;
stevep 0:04a9f72bbca7 1643 }
stevep 0:04a9f72bbca7 1644
stevep 0:04a9f72bbca7 1645
stevep 0:04a9f72bbca7 1646
stevep 0:04a9f72bbca7 1647 /*!
stevep 0:04a9f72bbca7 1648 *
stevep 0:04a9f72bbca7 1649 * standard mathematical operators
stevep 0:04a9f72bbca7 1650 *
stevep 0:04a9f72bbca7 1651 */
stevep 0:04a9f72bbca7 1652
stevep 0:04a9f72bbca7 1653
stevep 0:04a9f72bbca7 1654 /*!
stevep 0:04a9f72bbca7 1655 an operator for changing the sign
stevep 0:04a9f72bbca7 1656
stevep 0:04a9f72bbca7 1657 it's not changing 'this' but the changed value will be returned
stevep 0:04a9f72bbca7 1658 */
stevep 0:04a9f72bbca7 1659 Int<value_size> operator-() const
stevep 0:04a9f72bbca7 1660 {
stevep 0:04a9f72bbca7 1661 Int<value_size> temp(*this);
stevep 0:04a9f72bbca7 1662
stevep 0:04a9f72bbca7 1663 temp.ChangeSign();
stevep 0:04a9f72bbca7 1664
stevep 0:04a9f72bbca7 1665 return temp;
stevep 0:04a9f72bbca7 1666 }
stevep 0:04a9f72bbca7 1667
stevep 0:04a9f72bbca7 1668
stevep 0:04a9f72bbca7 1669 Int<value_size> operator-(const Int<value_size> & p2) const
stevep 0:04a9f72bbca7 1670 {
stevep 0:04a9f72bbca7 1671 Int<value_size> temp(*this);
stevep 0:04a9f72bbca7 1672
stevep 0:04a9f72bbca7 1673 temp.Sub(p2);
stevep 0:04a9f72bbca7 1674
stevep 0:04a9f72bbca7 1675 return temp;
stevep 0:04a9f72bbca7 1676 }
stevep 0:04a9f72bbca7 1677
stevep 0:04a9f72bbca7 1678
stevep 0:04a9f72bbca7 1679 Int<value_size> & operator-=(const Int<value_size> & p2)
stevep 0:04a9f72bbca7 1680 {
stevep 0:04a9f72bbca7 1681 Sub(p2);
stevep 0:04a9f72bbca7 1682
stevep 0:04a9f72bbca7 1683 return *this;
stevep 0:04a9f72bbca7 1684 }
stevep 0:04a9f72bbca7 1685
stevep 0:04a9f72bbca7 1686
stevep 0:04a9f72bbca7 1687 Int<value_size> operator+(const Int<value_size> & p2) const
stevep 0:04a9f72bbca7 1688 {
stevep 0:04a9f72bbca7 1689 Int<value_size> temp(*this);
stevep 0:04a9f72bbca7 1690
stevep 0:04a9f72bbca7 1691 temp.Add(p2);
stevep 0:04a9f72bbca7 1692
stevep 0:04a9f72bbca7 1693 return temp;
stevep 0:04a9f72bbca7 1694 }
stevep 0:04a9f72bbca7 1695
stevep 0:04a9f72bbca7 1696
stevep 0:04a9f72bbca7 1697 Int<value_size> & operator+=(const Int<value_size> & p2)
stevep 0:04a9f72bbca7 1698 {
stevep 0:04a9f72bbca7 1699 Add(p2);
stevep 0:04a9f72bbca7 1700
stevep 0:04a9f72bbca7 1701 return *this;
stevep 0:04a9f72bbca7 1702 }
stevep 0:04a9f72bbca7 1703
stevep 0:04a9f72bbca7 1704
stevep 0:04a9f72bbca7 1705 Int<value_size> operator*(const Int<value_size> & p2) const
stevep 0:04a9f72bbca7 1706 {
stevep 0:04a9f72bbca7 1707 Int<value_size> temp(*this);
stevep 0:04a9f72bbca7 1708
stevep 0:04a9f72bbca7 1709 temp.Mul(p2);
stevep 0:04a9f72bbca7 1710
stevep 0:04a9f72bbca7 1711 return temp;
stevep 0:04a9f72bbca7 1712 }
stevep 0:04a9f72bbca7 1713
stevep 0:04a9f72bbca7 1714
stevep 0:04a9f72bbca7 1715 Int<value_size> & operator*=(const Int<value_size> & p2)
stevep 0:04a9f72bbca7 1716 {
stevep 0:04a9f72bbca7 1717 Mul(p2);
stevep 0:04a9f72bbca7 1718
stevep 0:04a9f72bbca7 1719 return *this;
stevep 0:04a9f72bbca7 1720 }
stevep 0:04a9f72bbca7 1721
stevep 0:04a9f72bbca7 1722
stevep 0:04a9f72bbca7 1723 Int<value_size> operator/(const Int<value_size> & p2) const
stevep 0:04a9f72bbca7 1724 {
stevep 0:04a9f72bbca7 1725 Int<value_size> temp(*this);
stevep 0:04a9f72bbca7 1726
stevep 0:04a9f72bbca7 1727 temp.Div(p2);
stevep 0:04a9f72bbca7 1728
stevep 0:04a9f72bbca7 1729 return temp;
stevep 0:04a9f72bbca7 1730 }
stevep 0:04a9f72bbca7 1731
stevep 0:04a9f72bbca7 1732
stevep 0:04a9f72bbca7 1733 Int<value_size> & operator/=(const Int<value_size> & p2)
stevep 0:04a9f72bbca7 1734 {
stevep 0:04a9f72bbca7 1735 Div(p2);
stevep 0:04a9f72bbca7 1736
stevep 0:04a9f72bbca7 1737 return *this;
stevep 0:04a9f72bbca7 1738 }
stevep 0:04a9f72bbca7 1739
stevep 0:04a9f72bbca7 1740
stevep 0:04a9f72bbca7 1741 Int<value_size> operator%(const Int<value_size> & p2) const
stevep 0:04a9f72bbca7 1742 {
stevep 0:04a9f72bbca7 1743 Int<value_size> temp(*this);
stevep 0:04a9f72bbca7 1744 Int<value_size> remainder;
stevep 0:04a9f72bbca7 1745
stevep 0:04a9f72bbca7 1746 temp.Div(p2, remainder);
stevep 0:04a9f72bbca7 1747
stevep 0:04a9f72bbca7 1748 return remainder;
stevep 0:04a9f72bbca7 1749 }
stevep 0:04a9f72bbca7 1750
stevep 0:04a9f72bbca7 1751
stevep 0:04a9f72bbca7 1752 Int<value_size> & operator%=(const Int<value_size> & p2)
stevep 0:04a9f72bbca7 1753 {
stevep 0:04a9f72bbca7 1754 Int<value_size> remainder;
stevep 0:04a9f72bbca7 1755
stevep 0:04a9f72bbca7 1756 Div(p2, remainder);
stevep 0:04a9f72bbca7 1757 operator=(remainder);
stevep 0:04a9f72bbca7 1758
stevep 0:04a9f72bbca7 1759 return *this;
stevep 0:04a9f72bbca7 1760 }
stevep 0:04a9f72bbca7 1761
stevep 0:04a9f72bbca7 1762
stevep 0:04a9f72bbca7 1763 /*!
stevep 0:04a9f72bbca7 1764 Prefix operator e.g. ++variable
stevep 0:04a9f72bbca7 1765 */
stevep 0:04a9f72bbca7 1766 UInt<value_size> & operator++()
stevep 0:04a9f72bbca7 1767 {
stevep 0:04a9f72bbca7 1768 AddOne();
stevep 0:04a9f72bbca7 1769
stevep 0:04a9f72bbca7 1770 return *this;
stevep 0:04a9f72bbca7 1771 }
stevep 0:04a9f72bbca7 1772
stevep 0:04a9f72bbca7 1773
stevep 0:04a9f72bbca7 1774 /*!
stevep 0:04a9f72bbca7 1775 Postfix operator e.g. variable++
stevep 0:04a9f72bbca7 1776 */
stevep 0:04a9f72bbca7 1777 UInt<value_size> operator++(int)
stevep 0:04a9f72bbca7 1778 {
stevep 0:04a9f72bbca7 1779 UInt<value_size> temp( *this );
stevep 0:04a9f72bbca7 1780
stevep 0:04a9f72bbca7 1781 AddOne();
stevep 0:04a9f72bbca7 1782
stevep 0:04a9f72bbca7 1783 return temp;
stevep 0:04a9f72bbca7 1784 }
stevep 0:04a9f72bbca7 1785
stevep 0:04a9f72bbca7 1786
stevep 0:04a9f72bbca7 1787 UInt<value_size> & operator--()
stevep 0:04a9f72bbca7 1788 {
stevep 0:04a9f72bbca7 1789 SubOne();
stevep 0:04a9f72bbca7 1790
stevep 0:04a9f72bbca7 1791 return *this;
stevep 0:04a9f72bbca7 1792 }
stevep 0:04a9f72bbca7 1793
stevep 0:04a9f72bbca7 1794
stevep 0:04a9f72bbca7 1795 UInt<value_size> operator--(int)
stevep 0:04a9f72bbca7 1796 {
stevep 0:04a9f72bbca7 1797 UInt<value_size> temp( *this );
stevep 0:04a9f72bbca7 1798
stevep 0:04a9f72bbca7 1799 SubOne();
stevep 0:04a9f72bbca7 1800
stevep 0:04a9f72bbca7 1801 return temp;
stevep 0:04a9f72bbca7 1802 }
stevep 0:04a9f72bbca7 1803
stevep 0:04a9f72bbca7 1804
stevep 0:04a9f72bbca7 1805
stevep 0:04a9f72bbca7 1806 /*!
stevep 0:04a9f72bbca7 1807 *
stevep 0:04a9f72bbca7 1808 * input/output operators for standard streams
stevep 0:04a9f72bbca7 1809 *
stevep 0:04a9f72bbca7 1810 */
stevep 0:04a9f72bbca7 1811
stevep 0:04a9f72bbca7 1812 private:
stevep 0:04a9f72bbca7 1813
stevep 0:04a9f72bbca7 1814 /*!
stevep 0:04a9f72bbca7 1815 an auxiliary method for outputing to standard streams
stevep 0:04a9f72bbca7 1816 */
stevep 0:04a9f72bbca7 1817 template<class ostream_type, class string_type>
stevep 0:04a9f72bbca7 1818 static ostream_type & OutputToStream(ostream_type & s, const Int<value_size> & l)
stevep 0:04a9f72bbca7 1819 {
stevep 0:04a9f72bbca7 1820 string_type ss;
stevep 0:04a9f72bbca7 1821
stevep 0:04a9f72bbca7 1822 l.ToString(ss);
stevep 0:04a9f72bbca7 1823 s << ss;
stevep 0:04a9f72bbca7 1824
stevep 0:04a9f72bbca7 1825 return s;
stevep 0:04a9f72bbca7 1826 }
stevep 0:04a9f72bbca7 1827
stevep 0:04a9f72bbca7 1828
stevep 0:04a9f72bbca7 1829
stevep 0:04a9f72bbca7 1830 public:
stevep 0:04a9f72bbca7 1831
stevep 0:04a9f72bbca7 1832
stevep 0:04a9f72bbca7 1833 /*!
stevep 0:04a9f72bbca7 1834 output to standard streams
stevep 0:04a9f72bbca7 1835 */
stevep 0:04a9f72bbca7 1836 friend std::ostream & operator<<(std::ostream & s, const Int<value_size> & l)
stevep 0:04a9f72bbca7 1837 {
stevep 0:04a9f72bbca7 1838 return OutputToStream<std::ostream, std::string>(s, l);
stevep 0:04a9f72bbca7 1839 }
stevep 0:04a9f72bbca7 1840
stevep 0:04a9f72bbca7 1841
stevep 0:04a9f72bbca7 1842 #ifndef TTMATH_DONT_USE_WCHAR
stevep 0:04a9f72bbca7 1843
stevep 0:04a9f72bbca7 1844 /*!
stevep 0:04a9f72bbca7 1845 output to standard streams
stevep 0:04a9f72bbca7 1846 */
stevep 0:04a9f72bbca7 1847 friend std::wostream & operator<<(std::wostream & s, const Int<value_size> & l)
stevep 0:04a9f72bbca7 1848 {
stevep 0:04a9f72bbca7 1849 return OutputToStream<std::wostream, std::wstring>(s, l);
stevep 0:04a9f72bbca7 1850 }
stevep 0:04a9f72bbca7 1851
stevep 0:04a9f72bbca7 1852 #endif
stevep 0:04a9f72bbca7 1853
stevep 0:04a9f72bbca7 1854
stevep 0:04a9f72bbca7 1855
stevep 0:04a9f72bbca7 1856 private:
stevep 0:04a9f72bbca7 1857
stevep 0:04a9f72bbca7 1858 /*!
stevep 0:04a9f72bbca7 1859 an auxiliary method for converting from a string
stevep 0:04a9f72bbca7 1860 */
stevep 0:04a9f72bbca7 1861 template<class istream_type, class string_type, class char_type>
stevep 0:04a9f72bbca7 1862 static istream_type & InputFromStream(istream_type & s, Int<value_size> & l)
stevep 0:04a9f72bbca7 1863 {
stevep 0:04a9f72bbca7 1864 string_type ss;
stevep 0:04a9f72bbca7 1865
stevep 0:04a9f72bbca7 1866 // char or wchar_t for operator>>
stevep 0:04a9f72bbca7 1867 char_type z;
stevep 0:04a9f72bbca7 1868
stevep 0:04a9f72bbca7 1869 // operator>> omits white characters if they're set for ommiting
stevep 0:04a9f72bbca7 1870 s >> z;
stevep 0:04a9f72bbca7 1871
stevep 0:04a9f72bbca7 1872 if( z=='-' || z=='+' )
stevep 0:04a9f72bbca7 1873 {
stevep 0:04a9f72bbca7 1874 ss += z;
stevep 0:04a9f72bbca7 1875 s >> z; // we're reading a next character (white characters can be ommited)
stevep 0:04a9f72bbca7 1876 }
stevep 0:04a9f72bbca7 1877
stevep 0:04a9f72bbca7 1878 // we're reading only digits (base=10)
stevep 0:04a9f72bbca7 1879 while( s.good() && Misc::CharToDigit(z, 10)>=0 )
stevep 0:04a9f72bbca7 1880 {
stevep 0:04a9f72bbca7 1881 ss += z;
stevep 0:04a9f72bbca7 1882 z = static_cast<char_type>(s.get());
stevep 0:04a9f72bbca7 1883 }
stevep 0:04a9f72bbca7 1884
stevep 0:04a9f72bbca7 1885 // we're leaving the last readed character
stevep 0:04a9f72bbca7 1886 // (it's not belonging to the value)
stevep 0:04a9f72bbca7 1887 s.unget();
stevep 0:04a9f72bbca7 1888
stevep 0:04a9f72bbca7 1889 l.FromString(ss);
stevep 0:04a9f72bbca7 1890
stevep 0:04a9f72bbca7 1891 return s;
stevep 0:04a9f72bbca7 1892 }
stevep 0:04a9f72bbca7 1893
stevep 0:04a9f72bbca7 1894
stevep 0:04a9f72bbca7 1895 public:
stevep 0:04a9f72bbca7 1896
stevep 0:04a9f72bbca7 1897 /*!
stevep 0:04a9f72bbca7 1898 input from standard streams
stevep 0:04a9f72bbca7 1899 */
stevep 0:04a9f72bbca7 1900 friend std::istream & operator>>(std::istream & s, Int<value_size> & l)
stevep 0:04a9f72bbca7 1901 {
stevep 0:04a9f72bbca7 1902 return InputFromStream<std::istream, std::string, char>(s, l);
stevep 0:04a9f72bbca7 1903 }
stevep 0:04a9f72bbca7 1904
stevep 0:04a9f72bbca7 1905
stevep 0:04a9f72bbca7 1906 #ifndef TTMATH_DONT_USE_WCHAR
stevep 0:04a9f72bbca7 1907
stevep 0:04a9f72bbca7 1908 /*!
stevep 0:04a9f72bbca7 1909 input from standard streams
stevep 0:04a9f72bbca7 1910 */
stevep 0:04a9f72bbca7 1911 friend std::wistream & operator>>(std::wistream & s, Int<value_size> & l)
stevep 0:04a9f72bbca7 1912 {
stevep 0:04a9f72bbca7 1913 return InputFromStream<std::wistream, std::wstring, wchar_t>(s, l);
stevep 0:04a9f72bbca7 1914 }
stevep 0:04a9f72bbca7 1915 #endif
stevep 0:04a9f72bbca7 1916
stevep 0:04a9f72bbca7 1917
stevep 0:04a9f72bbca7 1918 };
stevep 0:04a9f72bbca7 1919
stevep 0:04a9f72bbca7 1920 } // namespace
stevep 0:04a9f72bbca7 1921
stevep 0:04a9f72bbca7 1922 #endif
stevep 0:04a9f72bbca7 1923