// Runge-Kutta 4 algorithm void System::RK4(){ vec2dN K1(nObj), K2(nObj), K3(nObj), K4(nObj); vec2dN L1(nObj), L2(nObj), L3(nObj), L4(nObj); vec2dN NewR(nObj), NewV(nObj); if (nObj == 1){ // If only ONE object K1 = h*derX(vec2dN(nObj)); L1 = h*(SunInf(vec2dN(nObj))); K2 = h*derX(L1*0.5); L2 = h*(SunInf(K1*0.5)); K3 = h*derX(L2*0.5); L3 = h*(SunInf(K2*0.5)); K4 = h*derX(L3); L4 = h*(SunInf(K3)); } else { // If more than one object if (!statSun){ // Sun mobile or not pressent K1 = h*derX(vec2dN(nObj)); L1 = h*derV(vec2dN(nObj)); K2 = h*derX(L1*0.5); L2 = h*derV(K1*0.5); K3 = h*derX(L2*0.5); L3 = h*derV(L2*0.5); K4 = h*derX(L3); L4 = h*derV(K4); } else { // If the sun is stationary K1 = h*derX(vec2dN(nObj)); L1 = h*(derV(vec2dN(nObj)) + SunInf(vec2dN(nObj))); K2 = h*derX(L1*0.5); L2 = h*(derV(K1*0.5) + SunInf(K1*0.5)); K3 = h*derX(L2*0.5); L3 = h*(derV(K2*0.5) + SunInf(K2*0.5)); K4 = h*derX(L3); L4 = h*(derV(K3) + SunInf(K3)); } } for (int i = 0 ; i < nObj ; i++){ NewR[i] = sys[i].relR + (K1[i] + 2*K2[i] + 2*K3[i] + K4[i])/(double)6; NewV[i] = sys[i].relV + (L1[i] + 2*L2[i] + 2*L3[i] + L4[i])/(double)6; } calc_potential(); for (int i = 0 ; i < nObj ; i++){ sys[i].update(NewR[i], NewV[i], sys[i].relT+h); } }
void divide_assignment_test() { quan::length::m L1(3.); L1 /=2; QUAN_CHECK_EQUAL(L1.numeric_value() , QUAN_FLOAT_TYPE(3.) / 2); quan::length::mm L2(-2310); L2 /= 2343; QUAN_CHECK_EQUAL(L2.numeric_value() ,QUAN_FLOAT_TYPE(-2310) / 2343); quan::length::in L3(-12); L3 /= 0.1; QUAN_CHECK_EQUAL(L3.numeric_value() ,QUAN_FLOAT_TYPE(-12) / 0.1 ); quan::length::in L4(0.314142); L4 /= 3.14142; QUAN_CHECK_EQUAL(L4.numeric_value() ,QUAN_FLOAT_TYPE(0.314142) / 3.14142); }
L004010A3( intOrPtr __edx // r3 ) { _unknown_ _t1; // _t1 _unknown_ _t3; // _t3 _unknown_ _t4; // _t4 _unknown_ _t5; // _t5 intOrPtr _t6; // _t6 _unknown_ _t7; // _t7 _t6 = __edx; _push( *fs:eax]); *fs:eax] = __esp; *((intOrPtr*)(0)) = _t6; asm("int 0x2e"); _push(0); asm("ror eax, cl"); _pop(__ecx); _t3 = 0x240026cb + _t6; L4(); _push(_t3); return; }
TEST( Commission , EquivalenceClass ) { srand(time(NULL)); for( int times = 0 ; times < 100000 ; ++times ) { vector<tuple<int,int,int>> dataSets; int sets = rand()%10+5; bool VALID_FLAG = true; bool TERM_FLAG = false; bool LOCK_ERR_FLAG = false ,STOCK_ERR_FLAG = false ,BARREL_ERR_FLAG = false; for( int i = 0 ; i < sets ; ++i ) { int l = num() , s = num() , b = num(); if( !L1(l) || !S1(s) || !B1(b) ) VALID_FLAG = false; if( L2(l) ) TERM_FLAG = true; if( L3(l) || L4(l) ) LOCK_ERR_FLAG = true; if( S2(s) || S3(s) ) STOCK_ERR_FLAG = true; if( B2(b) || B3(b) ) BARREL_ERR_FLAG = true; dataSets.emplace_back(make_tuple(l,s,b)); if( TERM_FLAG ) break; } //add terminator if( !TERM_FLAG ) if( num() % 4 != 3 ) // 75% chance { dataSets.emplace_back(make_tuple(-1,0,0)); TERM_FLAG = true; } else VALID_FLAG = false; // for any error, result will be invalid if( LOCK_ERR_FLAG || STOCK_ERR_FLAG || BARREL_ERR_FLAG || !TERM_FLAG ) VALID_FLAG = false; double result = retrieve(dataSets); if( VALID_FLAG == true ) { ASSERT_TRUE( 0 <= result ) << "Result is Valid but return error"; } else { // error code must match the flag switch(cms_error_code) { case TERM_ERROR: ASSERT_TRUE(!TERM_FLAG); break; case LOCK_ERROR: ASSERT_TRUE(LOCK_ERR_FLAG); break; case STOCK_ERROR: ASSERT_TRUE(STOCK_ERR_FLAG); break; case BARREL_ERROR: ASSERT_TRUE(BARREL_ERR_FLAG); break; case OK: break; default: ASSERT_TRUE(false) << "Fatel Error ,Code = " << cms_error_code << endl; } } } }
//------------------------------------------------------------------------------ virtual FP Generate() { nsArch::nsx86::Cx86HLAIntrinsics& HLA( *( dynamic_cast< nsArch::nsx86::Cx86HLAIntrinsics* >( m_pHLA ) ) ); nsArch::nsx86::CCPU& CPU = dynamic_cast< nsArch::nsx86::CCPU& >( TheMachine()->Logic().CPU() ); //static const Cmp_unsigned__int32 PAGESIZE = 4096; CPU.clear(); nsArch::nsx86::CLabel L1( CPU.newLabel() ); nsArch::nsx86::CLabel L2( CPU.newLabel() ); nsArch::nsx86::CLabel L3( CPU.newLabel() ); nsArch::nsx86::CLabel L4( CPU.newLabel() ); nsArch::nsx86::CLabel L5( CPU.newLabel() ); nsArch::nsx86::CLabel L6( CPU.newLabel() ); nsArch::nsx86::CLabel L7( CPU.newLabel() ); nsArch::nsx86::CLabel L8( CPU.newLabel() ); //CPU.int3(); CPU.push( CPU.reg_ebx() ); CPU.push( CPU.reg_edi() ); CPU.xor_( CPU.reg_edi(), CPU.reg_edi() ); //result sign assumed positive CPU.mov( CPU.reg_eax(), nsArch::nsx86::CMem( CPU.reg_esp(), 16 ) ); //Hi Word of dividend CPU.or_( CPU.reg_eax(), CPU.reg_eax() ); //test to see if signed CPU.jge( L1 ); //skip rest if a is already positive CPU.inc( CPU.reg_edi() ); //complement result sign flag bit CPU.mov( CPU.reg_edx(), nsArch::nsx86::CMem( CPU.reg_esp(), 12 ) ); //Lo Word of dividend CPU.neg( CPU.reg_eax() ); //make a positive CPU.neg( CPU.reg_edx() ); CPU.sbb( CPU.reg_eax(), 0 ); CPU.mov( nsArch::nsx86::CMem( CPU.reg_esp(), 16 ), CPU.reg_eax() ); //save positive value CPU.mov( nsArch::nsx86::CMem( CPU.reg_esp(), 12 ), CPU.reg_edx() ); CPU.bind( L1 ); CPU.mov( CPU.reg_eax(), nsArch::nsx86::CMem( CPU.reg_esp(), 24 ) ); //hi word of b CPU.or_( CPU.reg_eax(), CPU.reg_eax() ); //test to see if signed CPU.jge( L2 ); //skip rest if b is already positive CPU.mov( CPU.reg_edx(), nsArch::nsx86::CMem( CPU.reg_esp(), 20 ) ); //lo word of b CPU.neg( CPU.reg_eax() ); //make b positive CPU.neg( CPU.reg_edx() ); CPU.sbb( CPU.reg_eax(), 0 ); CPU.mov( nsArch::nsx86::CMem( CPU.reg_esp(), 24 ), CPU.reg_eax() ); CPU.mov( nsArch::nsx86::CMem( CPU.reg_esp(), 20 ), CPU.reg_edx() ); //save positive value CPU.bind( L2 ); CPU.or_( CPU.reg_eax(), CPU.reg_eax() ); //check to see if divisor < 4194304K CPU.jnz( L3 ); //nope, gotta do this the hard way CPU.mov( CPU.reg_ecx(), nsArch::nsx86::CMem( CPU.reg_esp(), 20 ) ); //load divisor CPU.mov( CPU.reg_eax(), nsArch::nsx86::CMem( CPU.reg_esp(), 16 ) ); //load high word of dividend CPU.xor_( CPU.reg_edx(), CPU.reg_edx() ); CPU.div( CPU.reg_ecx() ); //edx <- remainder CPU.mov( CPU.reg_eax(), nsArch::nsx86::CMem( CPU.reg_esp(), 12 ) ); //edx:eax <- remainder:lo word of dividend CPU.div( CPU.reg_ecx() ); //edx <- final remainder CPU.mov( CPU.reg_eax(), CPU.reg_edx() ); //edx:eax <- remainder CPU.xor_( CPU.reg_edx(), CPU.reg_edx() ); CPU.dec( CPU.reg_edi() ); //check result sign flag CPU.jns( L4 ); //negate result, restore stack and return CPU.jmp( L8 ); //result sign ok, restore stack and return CPU.bind( L3 ); CPU.mov( CPU.reg_ebx(), CPU.reg_eax() ); //ebx:ecx <- divisor CPU.mov( CPU.reg_ecx(), nsArch::nsx86::CMem( CPU.reg_esp(), 20 ) ); //load low word of divisor CPU.mov( CPU.reg_edx(), nsArch::nsx86::CMem( CPU.reg_esp(), 16 ) ); //load high word of dividend CPU.mov( CPU.reg_eax(), nsArch::nsx86::CMem( CPU.reg_esp(), 12 ) ); //load low word of dividend CPU.bind( L5 ); CPU.shr( CPU.reg_ebx(), 1 ); //shift divisor right one bit CPU.rcr( CPU.reg_ecx(), 1 ); CPU.shr( CPU.reg_edx(), 1 ); //shift dividend right one bit CPU.rcr( CPU.reg_eax(), 1 ); CPU.or_( CPU.reg_ebx(), CPU.reg_ebx() ); CPU.jnz( L5 ); //loop until divisor < 4194304K CPU.div( CPU.reg_ecx() ); //now divide, ignore remainder CPU.mov( CPU.reg_ecx(), CPU.reg_eax() ); //save a copy of quotient in ECX CPU.mul( nsArch::nsx86::dword_ptr( CPU.reg_esp(), 24 ) ); CPU.xchg( CPU.reg_ecx(), CPU.reg_eax() ); //save product, get quotient in EAX CPU.mul( nsArch::nsx86::dword_ptr( CPU.reg_esp(), 20 ) ); CPU.add( CPU.reg_edx(), CPU.reg_ecx() ); //EDX:EAX = QUOT * DVSR CPU.jc( L6 ); //carry means Quotient is off by 1 CPU.cmp( CPU.reg_edx(), nsArch::nsx86::CMem( CPU.reg_esp(), 16 ) ); //compare hi words of result and original CPU.ja( L6 ); //if result > original, do subtract CPU.jb( L7 ); //if result < original, we are ok CPU.cmp( CPU.reg_eax(), nsArch::nsx86::CMem( CPU.reg_esp(), 12 ) ); // hi words are equal, compare lo words CPU.jbe( L7 ); //if less or equal we are ok, else subtract CPU.bind( L6 ); CPU.sub( CPU.reg_eax(), nsArch::nsx86::CMem( CPU.reg_esp(), 20 ) ); //subtract divisor from result CPU.sbb( CPU.reg_edx(), nsArch::nsx86::CMem( CPU.reg_esp(), 24 ) ); CPU.bind( L7 ); CPU.sub( CPU.reg_eax(), nsArch::nsx86::CMem( CPU.reg_esp(), 12 ) ); //subtract dividend from result CPU.sbb( CPU.reg_edx(), nsArch::nsx86::CMem( CPU.reg_esp(), 16 ) ); CPU.dec( CPU.reg_edi() ); //check result sign flag CPU.jns( L8 ); //result is ok, restore stack and return CPU.bind( L4 ); CPU.neg( CPU.reg_edx() ); //otherwise, negate the result CPU.neg( CPU.reg_eax() ); CPU.sbb( CPU.reg_edx(), 0 ); CPU.bind( L8 ); CPU.pop( CPU.reg_edi() ); CPU.pop( CPU.reg_ebx() ); CPU.ret( nsArch::nsx86::CImm( 16 ) ); // Make JIT function. FP fn = reinterpret_cast< FP >( CPU.make() ); // Ensure that everything is ok and write the launchpad if( fn ) { m_bGenerated = true; if( m_pLaunchPad ) { HLA.WriteLaunchPad( (byte*)fn, m_pLaunchPad ); } } return fn; }
/* f3x5[] each symbol is 3x5 => 15 bits a-z offset 0 length 26 0-9 offset 26 length 10 # offset 36 length 1 */ unsigned short f3x5[] = { // A L1(011) | L2(101) | L3(101) | L4(111) | L5(101) , // B L1(110) | L2(101) | L3(110) | L4(101) | L5(110) , // C L1(011) | L2(101) | L3(100) | L4(100) | L5(011)