msvcp: fixed complex division

Andrey Zhezherun zhezherun at yandex.ru
Thu Oct 31 18:44:35 CDT 2013


This patch implements complex division correctly. The existing
implementation did something else which is not division.

Regards,
Andrey
-------------- next part --------------
--- wine-1.7.5.orig/dlls/msvcp71/math.c	2013-10-25 18:45:30.000000000 +0100
+++ wine-1.7.5/dlls/msvcp71/math.c	2013-10-31 17:41:43.000000000 +0000
@@ -1087,6 +1087,7 @@
 /* ??$?KM at std@@YA?AV?$complex at M@0 at AEBV10@0 at Z */
 complex_float* __cdecl complex_float_div(complex_float *ret, const complex_float *l, const complex_float *r)
 {
+    float rnom, inom, den;
     if((!r->real && !r->imag) || _isnan(l->real) || _isnan(l->imag)
             || _isnan(r->real) || _isnan(r->imag)) {
         ret->real = std_numeric_limits_float_quiet_NaN();
@@ -1094,16 +1095,11 @@
         return ret;
     }
 
-    ret->real = 0;
-    ret->imag = 0;
-    if(r->real) {
-        ret->real = l->real / r->real;
-        ret->imag = l->imag / r->real;
-    }
-    if(r->imag) {
-        ret->real += l->imag / r->imag;
-        ret->imag -= l->real / r->imag;
-    }
+    rnom = l->real * r->real + l->imag * r->imag;
+    inom = l->imag * r->real - l->real * r->imag;
+    den = r->real*r->real + r->imag*r->imag;
+    ret->real = rnom / den;
+    ret->imag = inom / den;
     return ret;
 }
 
@@ -1705,6 +1701,7 @@
 /* ??$?KO at std@@YA?AV?$complex at O@0 at AEBV10@0 at Z */
 complex_double* __cdecl complex_double_div(complex_double *ret, const complex_double *l, const complex_double *r)
 {
+    double rnom, inom, den;
     if((!r->real && !r->imag) || _isnan(l->real) || _isnan(l->imag)
             || _isnan(r->real) || _isnan(r->imag)) {
         ret->real = std_numeric_limits_double_quiet_NaN();
@@ -1712,16 +1709,11 @@
         return ret;
     }
 
-    ret->real = 0;
-    ret->imag = 0;
-    if(r->real) {
-        ret->real = l->real / r->real;
-        ret->imag = l->imag / r->real;
-    }
-    if(r->imag) {
-        ret->real += l->imag / r->imag;
-        ret->imag -= l->real / r->imag;
-    }
+    rnom = l->real * r->real + l->imag * r->imag;
+    inom = l->imag * r->real - l->real * r->imag;
+    den = r->real*r->real + r->imag*r->imag;
+    ret->real = rnom / den;
+    ret->imag = inom / den;
     return ret;
 }
 
--- wine-1.7.5.orig/dlls/msvcp80/math.c	2013-10-25 18:45:30.000000000 +0100
+++ wine-1.7.5/dlls/msvcp80/math.c	2013-10-31 17:41:30.000000000 +0000
@@ -1087,6 +1087,7 @@
 /* ??$?KM at std@@YA?AV?$complex at M@0 at AEBV10@0 at Z */
 complex_float* __cdecl complex_float_div(complex_float *ret, const complex_float *l, const complex_float *r)
 {
+    float rnom, inom, den;
     if((!r->real && !r->imag) || _isnan(l->real) || _isnan(l->imag)
             || _isnan(r->real) || _isnan(r->imag)) {
         ret->real = std_numeric_limits_float_quiet_NaN();
@@ -1094,16 +1095,11 @@
         return ret;
     }
 
-    ret->real = 0;
-    ret->imag = 0;
-    if(r->real) {
-        ret->real = l->real / r->real;
-        ret->imag = l->imag / r->real;
-    }
-    if(r->imag) {
-        ret->real += l->imag / r->imag;
-        ret->imag -= l->real / r->imag;
-    }
+    rnom = l->real * r->real + l->imag * r->imag;
+    inom = l->imag * r->real - l->real * r->imag;
+    den = r->real*r->real + r->imag*r->imag;
+    ret->real = rnom / den;
+    ret->imag = inom / den;
     return ret;
 }
 
@@ -1705,6 +1701,7 @@
 /* ??$?KO at std@@YA?AV?$complex at O@0 at AEBV10@0 at Z */
 complex_double* __cdecl complex_double_div(complex_double *ret, const complex_double *l, const complex_double *r)
 {
+    double rnom, inom, den;
     if((!r->real && !r->imag) || _isnan(l->real) || _isnan(l->imag)
             || _isnan(r->real) || _isnan(r->imag)) {
         ret->real = std_numeric_limits_double_quiet_NaN();
@@ -1712,16 +1709,11 @@
         return ret;
     }
 
-    ret->real = 0;
-    ret->imag = 0;
-    if(r->real) {
-        ret->real = l->real / r->real;
-        ret->imag = l->imag / r->real;
-    }
-    if(r->imag) {
-        ret->real += l->imag / r->imag;
-        ret->imag -= l->real / r->imag;
-    }
+    rnom = l->real * r->real + l->imag * r->imag;
+    inom = l->imag * r->real - l->real * r->imag;
+    den = r->real*r->real + r->imag*r->imag;
+    ret->real = rnom / den;
+    ret->imag = inom / den;
     return ret;
 }
 
--- wine-1.7.5.orig/dlls/msvcp90/math.c	2013-10-25 18:45:30.000000000 +0100
+++ wine-1.7.5/dlls/msvcp90/math.c	2013-10-31 17:41:10.000000000 +0000
@@ -1087,6 +1087,7 @@
 /* ??$?KM at std@@YA?AV?$complex at M@0 at AEBV10@0 at Z */
 complex_float* __cdecl complex_float_div(complex_float *ret, const complex_float *l, const complex_float *r)
 {
+    float rnom, inom, den;
     if((!r->real && !r->imag) || _isnan(l->real) || _isnan(l->imag)
             || _isnan(r->real) || _isnan(r->imag)) {
         ret->real = std_numeric_limits_float_quiet_NaN();
@@ -1094,16 +1095,11 @@
         return ret;
     }
 
-    ret->real = 0;
-    ret->imag = 0;
-    if(r->real) {
-        ret->real = l->real / r->real;
-        ret->imag = l->imag / r->real;
-    }
-    if(r->imag) {
-        ret->real += l->imag / r->imag;
-        ret->imag -= l->real / r->imag;
-    }
+    rnom = l->real*r->real + l->imag*r->imag;
+    inom = l->imag*r->real - l->real*r->imag;
+    den = r->real*r->real + r->imag*r->imag;
+    ret->real = rnom / den;
+    ret->imag = inom / den;
     return ret;
 }
 
@@ -1705,6 +1701,7 @@
 /* ??$?KO at std@@YA?AV?$complex at O@0 at AEBV10@0 at Z */
 complex_double* __cdecl complex_double_div(complex_double *ret, const complex_double *l, const complex_double *r)
 {
+    double rnom, inom, den;
     if((!r->real && !r->imag) || _isnan(l->real) || _isnan(l->imag)
             || _isnan(r->real) || _isnan(r->imag)) {
         ret->real = std_numeric_limits_double_quiet_NaN();
@@ -1712,16 +1709,11 @@
         return ret;
     }
 
-    ret->real = 0;
-    ret->imag = 0;
-    if(r->real) {
-        ret->real = l->real / r->real;
-        ret->imag = l->imag / r->real;
-    }
-    if(r->imag) {
-        ret->real += l->imag / r->imag;
-        ret->imag -= l->real / r->imag;
-    }
+    rnom = l->real * r->real + l->imag * r->imag;
+    inom = l->imag * r->real - l->real * r->imag;
+    den = r->real*r->real + r->imag*r->imag;
+    ret->real = rnom / den;
+    ret->imag = inom / den;
     return ret;
 }
 


More information about the wine-patches mailing list