كنت قد وضعت سابقا موضوع اسأل فيه عن كيفية عمل دالة sin و cos و كذلك دالة الأس و الجذر. و تم أرشادى لبعض الحلول لذا فقد بحثت عن افضل الأساليب لتضمينهم فوجدت ان افضلهم بلغة التجميع حيث ان بعض تلك الدوال معرفة للبروسسور. طبعا كتابة الكود لجميع الدوال بلغة التجميع غير فعالة - بالنسبة لى على الأقل. دعونى لا اطيل عليكم و اعطيكم النتيجة بشكل مباشر
struct Math{ static double log(double x); // Return natural logarithm of x (also called ln of x) static double log10(double x); // Return logarithm to base 10 of x static double exp(double x); // Return exponent of x static double alog10(double x); // Return anti-logarithm of x static double pow(double base,double exp); // Return base raised to exp static double root(double base,double exp); // Return base root of exp static double sqrt(double base); // Return Square root of base static double abs(double x); // Return absolute value of x static long mod(long x,long y); // Return the Reminder of dividing x over y static unsigned long long factorial(unsigned long long x); // Return Factorial of x static double floor(double x); // Returns the largest integer less than or equal to x static double ceiling(double x); // Returns the smallest integer greater than or equal to x static double sin(double x); // Return sine of x static double cos(double x); // Return cosine of x static double tan(double x); // Return tangent of x static double asin(double x); // Return angel (in radians) whose sine is x static double acos(double x); // Return angel (in radians) whose cosine is x static double atan(double x); // Return angel (in radians) whose tangent is x static double sinh(double x); // Return Hyperbolic sine of x static double cosh(double x); // Return Hyperbolic cosine of x static double tanh(double x); // Return Hyperbolic tangent of x static double asinh(double x); // Return angel (in radians) whose hyperbolic sine is x static double acosh(double x); // Return angel (in radians) whose hyperbolic cosine is x static double atanh(double x); // Return angel (in radians) whose hyperbolic tangent is x static long permute(long x, long y); // Return permutation of two numbers x and y static long combin (long x, long y); // Return combination of two numbers x and y static float* Pol(float x, float y); // Return 2 Element array contain r and theta(in radian) respectively in polar coordinate static float* Rec(float r, float theta); // Return 2 Element array contain x and y respectively in rectangular coordinate};
// preprocessor constants#define PI 3.14159265358979323846 // pi constant#define E 2.71828182845904523536 // exponent constant// preprocessor macros#define ToDegree(RAD) ((RAD * 180) / PI)#define ToRadian(DEG) ((DEG * PI ) / 180)// Private Interger powerdouble internalPwr(double num,int pwr){ double sum=1; for(int i=1;i<=pwr;i++) sum*=num; return sum;}long factor_condition(long from, long to){ long sum=1; for (long i=from; i>=to; i--) sum*=i; return sum;}double Math::log(double x){ _asm { fld x // push the x parameer into stack fld1 // push 1 to stack (because fyl2x require that st(0) to be greater than 0) fxch // swap st(1) and st(0) fyl2x // Compute 1 * log(x) fldl2e // Load e fdiv // apply the division log(x)/log(e) }}double Math::log10(double x){ const double base10 = 2.3025850929940456840179914546844; return log(x) / base10;}double Math::exp(double x){ return pow(E,x); }double Math::alog10(double x){ const double multi = x * 3.3219280948873626; // x * ln(10)/ln(2) _asm { fld multi // push multi on top of floating-point stack fld st(0) // Duplicate tos. fld st(0) frndint // Compute integer portion. fxch // Swap whole and int values. fsub st(0), st(1) // Compute fractional part. f2xm1 // Compute 2^frac(x)-1. fld1 fadd // Compute 2^frac(x). fxch // Get integer portion. fld1 // Compute 1*2**int(x). fscale fstp st(1) // Remove st(1) (which is 1). fmul // Compute 2^int(x) * 2**frac(x). }}double Math::pow(double base,double exp){ return alog10(log10(base) * exp); }double Math::root(double base,double exp){ return alog10(log10(base) / exp); }double Math::sqrt(double base){return root(base,2); }double Math::abs(double x){ return x<0 ? -x : x; }long Math::mod(long x,long y){ return x - ((x/y) * y); }unsigned long long Math::factorial(unsigned long long x){ unsigned long long sum=1; for (unsigned long long i=x; i>=1; i--) sum*=i; return sum;}double Math::ceiling(double x){ return (double)((x > (long)x) ? ((long)x+1) : ((long)x) ); }double Math::floor(double x){ return (double)((x < (long)x) ? ((long)x-1) : ((long)x) ); }double Math::sin(double x){ float angel[]={0,30,90,180,210,270,360}; // angle lookup table for readable number and float values[]={0,0.5,1,0,-0.5,-1,0}; // it's values in degree double deg=ToDegree(x); // convert x to degree for (;;) if (deg>=360) // if x greater than 360 deg-=360; // decrease it by 360 else // otherwise break; // break infinite loop for (int c=0; c<7; c++) // search look up table for angle if (deg==angel[c]) // if exist return values[c]; // return its value // now i'll calculate sin using formula // sin x = x - (x^3/3!) + (x^5/5!) - (x^7/7!) .... double numerator = x; double denominator = 1.0; double sign = 1.0; double value = 0; for ( int i = 1; i <= 10; i++ ) { value += numerator / denominator * sign; numerator *= x * x; denominator *= i*2 * (i*2+1); sign *= -1; } return value;}double Math::cos(double x){ float angel[]={0,90,120,180,270,300,360}; float values[]={1,0,-0.5,-1,0,0.5,1}; double deg=ToDegree(x); for (;;) if (deg>=360) deg-=360; else break; for (int c=0; c<7; c++) if (deg==angel[c]) return values[c]; double numerator = 1.0; double denominator = 1.0; double sign = 1.0; double cos = 0; for ( int i = 1; i <= 10; i++ ) { cos += numerator / denominator * sign; sign *= -1; numerator *= x * x; denominator *= (i*2-1) * i*2; } return cos;}double Math::tan(double x){ return sin(x)/cos(x); }long Math::permute(long x, long y){ // معادلة حساب التباديل لرقمين x و y if (y>x) throw "y can not be greater than x"; if (y==1) return x; if (y==0) return 1; if (x==y || x==y-1) return factor_condition(x,2); return factor_condition(x,x-y+1);}long Math::combin(long x, long y){ // معادلة حساب التوافيق لرقمين x و y if (y>x) throw "y can not be greater than x"; if (y==1 || x==y-1) return x; if (y==x || y==0) return 1; return factor_condition(x,x-y+1)/factor_condition(y,2);}