Có thể tham khảo ở đây:
http://www.tc.umn.edu/~ringx004/sidebar.html
Hàm sin được tính thế nào trong Math ?
Khai triển Taylor :
hay phương pháp nào khác ?
C Code:
Ở đây cần tính chính xác tới 0.00 000 01, (0.0000001) thôi
Mại dzô, mời vô tham gia !
Phọt mô xa 2016
Có thể tham khảo ở đây:
http://www.tc.umn.edu/~ringx004/sidebar.html
Tính gần đúng:
C Code:
#include <stdio.h> #include <math.h> #define EPSILON 0.0000001 #define mAbs(x) x>0?x:-x double sinCalc(const double x){ int k = 1; double kq = x, tg = x; //while(kq += tg *= -x*x/(2*k)/(2*k++ + 1), mAbs(tg)> EPSILON); do{ tg *= -x*x/(2*k)/(2*k+1); //P(k) = P(k-1)* df(k) kq += tg; //Sin(k) = Sin(k-1) + P(k) k++; } while(mAbs(tg)> EPSILON); // return kq; } int main(){ double x, y; // // y = sinCalc(x); }
Mại dzô, mời vô tham gia !
Phọt mô xa 2016
Hy vọng đây là bài viết cuối của topic này, sẽ không có cách nào nhanh hơn, tối ưu hon bằng viết bằng asm (viết theo source code pascal)
C Code:
Phọt mô xa 2016
Tuỳ trình biên dịch, TBD c/c++ khác nhau sử dụng keyword. syntax khác nhau. Code trên viết cho Borland c; nhưng biên dịch với Ms sẽ báo lỗi. Sửa lại
C++ Code:
#include <stdio.h> #include <math.h> double sinCalc(const double X){ __asm{ FLD X FSIN FWAIT } } int main(){ double x, y; printf("\ninput x = "); scanf("%lf", &x); // y = sin(x); printf("\n(Math) y = %f", y); // y = sinCalc(x); printf("\n(Calc) y = %f", y); }
Biên dịch với MsC++, cl.exe (cmd mode)
Cmd Code:
cl SinAsm.cpp echo test F:\_Abc_\_Test_\_mGw_Asm>SinAsm input x = 1.2345 (Math) y = 0.943983 (Calc) y = 0.943983
Tương tự cần viết lại để biên dịch với MinGW, gcc hay g++
Phọt mô xa 2016
Bài viết đáng tham khảo.
Hàm pow (inline assembly)
Pascal Code:
program Pow; {$APPTYPE CONSOLE} uses SysUtils //, math ; function PowerA(const Base, Exponent: Extended): Extended; const Max : Double = MaxInt; var IntExp : Integer; asm fld Exponent fld st {copy to st(1)} fabs {abs(exp)} fld Max fcompp {leave exp in st(0)} fstsw ax sahf jb @@RealPower {exp > MaxInt} fld st {exp in st(0) and st(1)} frndint {round(exp)} fcomp {compare exp and round(exp)} fstsw ax sahf jne @@RealPower fistp IntExp mov eax, IntExp {eax=Trunc(Exponent)} mov ecx, eax cdq fld1 {Result=1} xor eax, edx sub eax, edx {abs(exp)} jz @@Exit fld Base jmp @@Entry @@Loop: fmul st, st {Base * Base} @@Entry: shr eax, 1 jnc @@Loop fmul st(1), st {Result * X} jnz @@Loop fstp st cmp ecx, 0 jge @@Exit fld1 fdivrp {1/Result} jmp @@Exit @@RealPower: fld Base ftst fstsw ax sahf jz @@Done fldln2 fxch fyl2x fxch fmulp st(1), st fldl2e fmulp st(1), st fld st(0) frndint fsub st(1), st fxch st(1) f2xm1 fld1 faddp st(1), st fscale @@Done: fstp st(1) @@Exit: end; var x, y, kq : Extended; begin writeln('==== Calc x^y ====='); write('input x = '); read(x); write('and y = '); read(y); // kq := PowerA(x, y); //Gọi hàm inline assembly // writeln('resutl, power = ', FormatFloat('#,###', kq)); //định dạng với thousand format readln; end.
C++ Code:
#include <stdio.h> #include <windows.h> double sqrt(double X){ __asm{ FLD X FSQRT FWAIT } } int main(){ UINT cp = GetConsoleOutputCP(); SetConsoleOutputCP(CP_UTF8); printf("\nGiải phương trình bậc hai: aX² + bX + c = 0\n"); //0xB2 ², Superscripts 2 float a, b, c; printf("Nhập hệ số a = "); scanf("%f", &a); printf("Nhập hệ số b = "); scanf("%f", &b); printf("Nhập hệ số c = "); scanf("%f", &c); double delta = b*b -4*a*c; if(delta < 0){ printf("\nPhương trình vô nghiệm (nghiệm ảo), delta: %lf < 0 ", delta); //return -1; } else if(delta == 0){ printf("\nPhương trình nghiệm kép, x = %lf", -b / (2*a)); //return 1; } else{ double rt = sqrt(delta); printf("\nPhương trình có hai nghiệm: sqrt(%lf) = %lf", delta, rt); printf("\n x₁ = %lf", (-b + rt) / (2*a)); //# 0x2081 ₁, Subscript One printf("\n x₂ = %lf", (-b - rt) / (2*a)); //# 0x2082 ₂, Subscript Two } if(cp != 0) SetConsoleOutputCP(cp); return 0; }
...
..
.
Hay. Code đó có chạy đúng trên mọi máy không dzậy. Hiện giờ tôi chưa có pc nên chưa thử được
Assembly inline cho Gcc (MinGW) viết khác Borland và Microsoft:
Trước trong cviet có, chắc nó bị xoá mất.C Code:
float sinx( float degree ) { float result, two_right_angles = 180.0f ; __asm__ __volatile__ ( "fld %1;" "fld %2;" "fldpi;" "fmul;" "fdiv;" "fsin;" "fstp %0;" : "=g" (result) : "g"(two_right_angles), "g" (degree) ) ; return result ; }
https://www.codeproject.com/Articles/15971/Using-Inline-Assembly-in-C-C
...
..
.