Changeset b391de in git for factory/int_intdiv.cc
- Timestamp:
- Apr 6, 1998, 2:06:48 PM (26 years ago)
- Branches:
- (u'spielwiese', '91e5db82acc17434e4062bcfa44e6efa7d41fd30')
- Children:
- 1d418066c3ae5964017d4db2d217ad8886378c2c
- Parents:
- 2e61d1c36b49ff9e3b6689855597e8a149fb806a
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
factory/int_intdiv.cc
r2e61d1c rb391de 1 1 /* emacs edit mode for this file is -*- C++ -*- */ 2 /* $Id: int_intdiv.cc,v 1. 2 1998-03-17 15:57:00schmidt Exp $ */2 /* $Id: int_intdiv.cc,v 1.3 1998-04-06 12:06:48 schmidt Exp $ */ 3 3 4 4 //{{{ docu … … 18 18 #include "ftmpl_functions.h" 19 19 20 #include "stdio.h"21 22 20 //{{{ InternalCF * InternalInteger::dividesame, dividecoeff ( InternalCF * c ) 23 21 // docu: see CanonicalForm::operator /() … … 75 73 mpz_init_set_si( &n, intC ); 76 74 mpz_init_set( &d, &thempi ); 77 } 78 else {75 } else { 76 mpz_init_set( &n, &thempi ); 79 77 mpz_init_set_si( &d, intC ); 80 mpz_init_set( &n, &thempi );81 78 } 82 79 if ( deleteObject() ) delete this; … … 88 85 int mpiSign = mpz_sgn( &thempi ); 89 86 if ( deleteObject() ) delete this; 90 if ( intC > 0 )87 if ( intC >= 0 ) 91 88 return int2imm( 0 ); 92 89 else … … 123 120 "type error: InternalInteger expected" ); 124 121 122 if ( c == this ) { 123 if ( deleteObject() ) delete this; 124 return int2imm( 1 ); 125 } 126 125 127 if ( getRefCount() > 1 ) { 126 128 deleteObject(); … … 140 142 ASSERT( ::is_imm( c ) == INTMARK, 141 143 "type error: immediate integer expected" ); 142 ASSERT( ! invert || imm2int( c ) == 0, "math error: c does not divide CO" ); 144 ASSERT( invert || imm2int( c ) != 0, 145 "math error: divide by zero" ); 146 ASSERT( ! invert || imm2int( c ) == 0, 147 "math error: c does not divide CO" ); 143 148 144 149 if ( invert ) { … … 165 170 //}}} 166 171 167 // we have to divide the immediate integer `c' by CO.168 // If `c' is positive, this is quite simple: we169 // simply return `c'. If `c' is negative we return170 // abs(CO)-abs(`c').171 // we have to divide CO by the immediate integer `c'.172 // The remainder will be less than the absolute value of173 // `c', hence it will fit again into an immediate.174 175 172 //{{{ InternalCF * InternalInteger::modulosame, modulocoeff ( InternalCF * c ) 176 173 // docu: see CanonicalForm::operator %() … … 181 178 "type error: InternalInteger expected" ); 182 179 183 if ( cf_glob_switches.isOn( SW_RATIONAL ) || c == this) {180 if ( (c == this) || cf_glob_switches.isOn( SW_RATIONAL ) ) { 184 181 if ( deleteObject() ) delete this; 185 182 return int2imm( 0 ); … … 211 208 } 212 209 213 InternalCF * result;214 215 210 int intC = imm2int( c ); 216 211 217 212 if ( invert ) { 218 // calculate c % CO219 if ( intC > 0 )220 re sult = int2imm( intC );221 else {213 if ( intC >= 0 ) { 214 if ( deleteObject() ) delete this; 215 return c; 216 } else { 222 217 // no checks for refCount == 1 are done. It is not worth ... 223 218 MP_INT mpiResult; … … 225 220 mpz_abs( &mpiResult, &mpiResult ); 226 221 mpz_sub_ui( &mpiResult, &mpiResult, -intC ); 227 result = uiNormalizeMPI( mpiResult );228 }229 } else { 230 // calculate CO % c 222 if ( deleteObject() ) delete this; 223 return uiNormalizeMPI( mpiResult ); 224 } 225 } else { 231 226 MP_INT dummy; 232 227 mpz_init( &dummy ); 233 result = int2imm( mpz_mod_ui( &dummy, &thempi, (intC > 0 ? intC : -intC) ) );228 InternalCF * result = int2imm( mpz_mod_ui( &dummy, &thempi, tabs( intC ) ) ); 234 229 mpz_clear( &dummy ); 235 } 236 237 // clean up 238 if ( deleteObject() ) delete this; 239 return result; 230 if ( deleteObject() ) delete this; 231 return result; 232 } 240 233 } 241 234 //}}} … … 261 254 InternalInteger::divremsame ( InternalCF * c, InternalCF * & quot, InternalCF * & rem ) 262 255 { 263 if ( cf_glob_switches.isOn( SW_RATIONAL ) ) { 264 quot = copyObject(); 265 quot = quot->dividesame( c ); 266 rem = int2imm( 0 ); 267 } 268 else if ( c == this ) { 256 ASSERT( ! ::is_imm( c ) && c->levelcoeff() == IntegerDomain, 257 "type error: InternalInteger expected" ); 258 259 if ( c == this ) { 269 260 quot = int2imm( 1 ); 270 261 rem = int2imm( 0 ); 271 } 272 else { 273 MP_INT q; 274 MP_INT r; 275 mpz_init( &q ); mpz_init( &r ); 276 int signmpi = mpz_cmp_si( &thempi, 0 ); 277 int signc = mpz_cmp_si( &MPI( c ), 0 ); 278 if ( signmpi < 0 ) 279 mpz_neg( &thempi, &thempi ); 280 if ( signc < 0 ) 281 mpz_neg( &MPI( c ), &MPI( c ) ); 282 mpz_divmod( &q, &r, &thempi, &MPI( c ) ); 283 if ( signmpi < 0 && mpz_cmp_si( &r, 0 ) != 0 ) { 284 mpz_sub( &r, &MPI( c ), &r ); 285 } 286 if ( signmpi < 0 ) 287 mpz_neg( &thempi, &thempi ); 288 if ( signc < 0 ) 289 mpz_neg( &MPI( c ), &MPI( c ) ); 290 if ( signmpi < 0 && signc < 0 ) { 291 if ( mpz_cmp_si( &r, 0 ) != 0 ) 292 mpz_add_ui( &q, &q, 1 ); 293 } 294 else if ( signc < 0 ) 295 mpz_neg( &q, &q ); 296 else if ( signmpi < 0 ) { 297 mpz_neg( &q, &q ); 298 if ( mpz_cmp_si( &r, 0 ) != 0 ) 299 mpz_sub_ui( &q, &q, 1 ); 300 } 301 if ( mpz_is_imm( &q ) ) 302 quot = int2imm( mpz_get_si( &q ) ); 303 else 304 quot = new InternalInteger( q ); 305 if ( mpz_is_imm( &r ) ) 306 rem = int2imm( mpz_get_si( &r ) ); 307 else 308 rem = new InternalInteger( r ); 309 } 262 return; 263 } 264 265 if ( cf_glob_switches.isOn( SW_RATIONAL ) ) { 266 MP_INT n, d; 267 mpz_init_set( &n, &thempi ); 268 mpz_init_set( &d, &MPI( c ) ); 269 InternalRational * result = new InternalRational( n, d ); 270 quot = result->normalize_myself(); 271 rem = int2imm( 0 ); 272 return; 273 } 274 275 MP_INT q; 276 MP_INT r; 277 mpz_init( &q ); mpz_init( &r ); 278 if ( mpz_sgn( &MPI( c ) ) > 0 ) 279 mpz_fdiv_qr( &q, &r, &thempi, &MPI( c ) ); 280 else 281 mpz_cdiv_qr( &q, &r, &thempi, &MPI( c ) ); 282 283 quot = normalizeMPI( q ); 284 rem = uiNormalizeMPI( r ); 310 285 } 311 286 … … 313 288 InternalInteger::divremcoeff ( InternalCF * c, InternalCF * & quot, InternalCF * & rem, bool invert ) 314 289 { 315 ASSERT( ::is_imm( c ) == INTMARK, "incompatible base coefficients" ); 316 317 if ( cf_glob_switches.isOn( SW_RATIONAL ) ) { 318 quot = copyObject(); 319 quot = quot->dividecoeff( c, invert ); 290 ASSERT( ::is_imm( c ) == INTMARK, 291 "type error: immediate integer expected" ); 292 ASSERT( invert || imm2int( c ) != 0, 293 "math error: divide by zero" ); 294 295 int intC = imm2int( c ); 296 297 if ( cf_glob_switches.isOn( SW_RATIONAL ) ) { 298 MP_INT n, d; 299 if ( invert ) { 300 mpz_init_set_si( &n, intC ); 301 mpz_init_set( &d, &thempi ); 302 } else { 303 mpz_init_set( &n, &thempi ); 304 mpz_init_set_si( &d, intC ); 305 } 306 InternalRational * result = new InternalRational( n, d ); 307 quot = result->normalize_myself(); 320 308 rem = int2imm( 0 ); 321 309 return; 322 310 } 323 quot = copyObject(); 324 quot = quot->divcoeff( c, invert ); 325 rem = copyObject(); 326 rem = rem->modcoeff( c, invert ); 327 return; 328 int cc = imm2int( c ); 329 MP_INT q, r; 330 int signmpi = mpz_cmp_si( &thempi, 0 ); 331 int signc = cc; 332 333 mpz_init( &q ); mpz_init( &r ); 334 if ( signmpi < 0 ) 335 mpz_neg( &thempi, &thempi ); 336 if ( signc < 0 ) 337 cc = -cc; 311 338 312 if ( invert ) { 339 MP_INT ccc; 340 mpz_init_set_si( &ccc, cc ); 341 mpz_divmod( &q, &r, &ccc, &thempi ); 342 mpz_clear( &ccc ); 343 if ( signc < 0 && signmpi < 0 ) { 344 if ( mpz_cmp_si( &r, 0 ) != 0 ) { 345 mpz_add_ui( &q, &q, 1 ); 346 mpz_sub( &r, &thempi, &r ); 347 } 348 } 349 else if ( signc < 0 ) { 350 if ( mpz_cmp_si( &r, 0 ) != 0 ) { 351 mpz_add_ui( &q, &q, 1 ); 352 mpz_neg( &q, &q ); 353 mpz_sub( &r, &thempi, &r ); 354 } 355 } 356 else if ( signmpi < 0 ) 313 if ( intC >= 0 ) { 314 rem = c; 315 quot = int2imm( 0 ); 316 } else { 317 MP_INT mpiResult; 318 mpz_init_set( &mpiResult, &thempi ); 319 mpz_abs( &mpiResult, &mpiResult ); 320 mpz_sub_ui( &mpiResult, &mpiResult, -intC ); 321 rem = uiNormalizeMPI( mpiResult ); 322 quot = int2imm( -mpz_sgn( &thempi ) ); 323 } 324 } else { 325 MP_INT q; 326 MP_INT dummy; 327 mpz_init( &q ); mpz_init( &dummy ); 328 if ( intC > 0 ) { 329 rem = int2imm( mpz_fdiv_qr_ui( &q, &dummy, &thempi, intC ) ); 330 quot = normalizeMPI( q ); 331 } else { 332 rem = int2imm( mpz_fdiv_qr_ui( &q, &dummy, &thempi, -intC ) ); 357 333 mpz_neg( &q, &q ); 358 } 359 else { 360 mpz_divmod_ui( &q, &r, &thempi, cc ); 361 if ( signmpi < 0 && signc < 0 ) { 362 if ( mpz_cmp_si( &r, 0 ) != 0 ) { 363 mpz_add_ui( &q, &q, 1 ); 364 mpz_neg( &r, &r ); 365 mpz_add_ui( &r, &r, cc ); 366 } 367 } 368 else if ( signmpi < 0 ) { 369 if ( mpz_cmp_si( &r, 0 ) != 0 ) { 370 mpz_add_ui( &q, &q, 1 ); 371 mpz_neg( &q, &q ); 372 mpz_neg( &r, &r ); 373 mpz_add_ui( &r, &r, cc ); 374 } 375 } 376 else if ( signc < 0 ) 377 mpz_neg( &q, &q ); 378 } 379 if ( signmpi < 0 ) 380 mpz_neg( &thempi, &thempi ); 381 if ( mpz_is_imm( &r ) ) { 382 rem = int2imm( mpz_get_si( &r ) ); 383 mpz_clear( &r ); 384 } 385 else 386 rem = new InternalInteger( r ); 387 if ( mpz_is_imm( &q ) ) { 388 quot = int2imm( mpz_get_si( &q ) ); 389 mpz_clear( &q ); 390 } 391 else 392 quot = new InternalInteger( q ); 334 quot = normalizeMPI( q ); 335 } 336 mpz_clear( &dummy ); 337 } 393 338 } 394 339 //}}} … … 406 351 InternalInteger::divremcoefft ( InternalCF * c, InternalCF * & quot, InternalCF * & rem, bool invert ) 407 352 { 408 ASSERT( ::is_imm( c ) == INTMARK, "incompatible base coefficients" );409 353 divremcoeff( c, quot, rem, invert ); 410 354 return true;
Note: See TracChangeset
for help on using the changeset viewer.