[grisbi-cvs] grisbi/src gsb_real.c, 1.42, 1.43 gsb_real_cunit.c, 1.8, 1.9

Mickaƫl Remars mykeul at users.sourceforge.net
Wed May 20 23:15:09 CEST 2009


Update of /cvsroot/grisbi/grisbi/src
In directory ddv4jf1.ch3.sourceforge.com:/tmp/cvs-serv31915/src

Modified Files:
	gsb_real.c gsb_real_cunit.c 
Log Message:
Added a new unit-test on gsb_real_mul(), and rewrote the function to make all the tests working (+ refactored gsb_real_minimize_exponent() to avoid duplicated code)

Index: gsb_real.c
===================================================================
RCS file: /cvsroot/grisbi/grisbi/src/gsb_real.c,v
retrieving revision 1.42
retrieving revision 1.43
diff -u -d -r1.42 -r1.43
--- gsb_real.c	20 May 2009 20:49:20 -0000	1.42
+++ gsb_real.c	20 May 2009 21:15:06 -0000	1.43
@@ -414,21 +414,35 @@
  * reduce the exponent to its smallest possible value,
  * without losing any precision
  *
- * \param num a pointer to the number to be reduced
+ * \param mantissa a pointer to the 64 bits mantissa to be reduced
+ * \param exponent a pointer to the exponent to be reduced
  **/
-void gsb_real_minimize_exponent ( gsb_real *num )
+void gsb_real_raw_minimize_exponent ( gint64 *mantissa, gint *exponent )
 {
-    while ( num->exponent > 0 )
+    while ( *exponent > 0 )
     {
-        ldiv_t d = ldiv ( num->mantissa, 10 );
+        lldiv_t d = lldiv ( *mantissa, 10 );
         if ( d.rem != 0 )
             return;
-        num->mantissa = d.quot;
-        --num->exponent;
+        *mantissa = d.quot;
+        --*exponent;
     }
 }
 
 /**
+ * reduce the exponent to its smallest possible value,
+ * without losing any precision
+ *
+ * \param num a pointer to the number to be reduced
+ **/
+void gsb_real_minimize_exponent ( gsb_real *num )
+{
+    gint64 mantissa = num->mantissa;
+    gsb_real_raw_minimize_exponent ( &mantissa, &num->exponent);
+    num->mantissa = mantissa;
+}
+
+/**
  * grow the exponent up to target_exponent
  * (only if possible without losing precision)
  *
@@ -589,13 +603,17 @@
  * \param number_1
  * \param number_2
  *
- * \return the multiplication between the 2
+ * \return the multiplication between the 2, or error_real if an overflow occured
  * */
 gsb_real gsb_real_mul ( gsb_real number_1,
                         gsb_real number_2 )
 {
-    number_1.mantissa *= number_2.mantissa;
+    gint64 mantissa = (gint64)number_1.mantissa * number_2.mantissa;
     number_1.exponent += number_2.exponent;
+    gsb_real_raw_minimize_exponent ( &mantissa, &number_1.exponent );
+    if ( ( mantissa > G_MAXLONG ) || ( mantissa < G_MINLONG ) )
+        return error_real;
+    number_1.mantissa = mantissa;
     return number_1;
 }
 

Index: gsb_real_cunit.c
===================================================================
RCS file: /cvsroot/grisbi/grisbi/src/gsb_real_cunit.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- gsb_real_cunit.c	20 May 2009 19:49:29 -0000	1.8
+++ gsb_real_cunit.c	20 May 2009 21:15:06 -0000	1.9
@@ -324,6 +324,71 @@
     CU_ASSERT_EQUAL ( 0, r.exponent );
 }
 
+void gsb_real_cunit__gsb_real_mul()
+{
+    gsb_real a = { 12, 1 };
+    gsb_real b = { 31415, 4 };
+    gsb_real r = gsb_real_mul ( a, b );
+    CU_ASSERT_EQUAL ( 37698, r.mantissa );
+    CU_ASSERT_EQUAL ( 4, r.exponent );
+    
+    a.mantissa = 0x7FFFFFFF;
+    a.exponent = 0;
+    b.mantissa = 2;
+    b.exponent = 0;
+    r = gsb_real_mul ( a, b );
+    CU_ASSERT_EQUAL ( 0x80000000, r.mantissa );
+    CU_ASSERT_EQUAL ( 0, r.exponent );
+    
+    a.mantissa = 0x7FFFFFFF;
+    a.exponent = 0;
+    b.mantissa = 9;
+    b.exponent = 1;
+    r = gsb_real_mul ( a, b );
+    CU_ASSERT_EQUAL ( 0x80000000, r.mantissa );
+    CU_ASSERT_EQUAL ( 0, r.exponent );
+    
+    a.mantissa = 0x80000001;
+    a.exponent = 0;
+    b.mantissa = 2;
+    b.exponent = 0;
+    r = gsb_real_mul ( a, b );
+    CU_ASSERT_EQUAL ( 0x80000000, r.mantissa );
+    CU_ASSERT_EQUAL ( 0, r.exponent );
+
+    a.mantissa = 0x80000000;
+    a.exponent = 0;
+    b.mantissa = 9;
+    b.exponent = 1;
+    r = gsb_real_mul ( a, b );
+    CU_ASSERT_EQUAL ( 0x80000000, r.mantissa );
+    CU_ASSERT_EQUAL ( 0, r.exponent );
+
+    a.mantissa = 100;
+    a.exponent = 0;
+    b.mantissa = 0x80000000;
+    b.exponent = 0;
+    r = gsb_real_mul(a, b);
+    CU_ASSERT_EQUAL ( 0x80000000, r.mantissa );
+    CU_ASSERT_EQUAL ( 0, r.exponent );
+
+    a.mantissa = 22000;
+    a.exponent = 0;
+    b.mantissa = 100000;
+    b.exponent = 0;
+    r = gsb_real_mul ( a, b );
+    CU_ASSERT_EQUAL ( 0x80000000, r.mantissa );
+    CU_ASSERT_EQUAL ( 0, r.exponent );
+
+    a.mantissa = -22000;
+    a.exponent = 0;
+    b.mantissa = 100000;
+    b.exponent = 0;
+    r = gsb_real_mul ( a, b );
+    CU_ASSERT_EQUAL ( 0x80000000, r.mantissa );
+    CU_ASSERT_EQUAL ( 0, r.exponent );
+}
+
 CU_pSuite gsb_real_cunit_create_suite ( void )
 {
     CU_pSuite pSuite = CU_add_suite("gsb_real",
@@ -337,6 +402,7 @@
     || (NULL == CU_add_test(pSuite, "of gsb_real_gsb_real_normalize()",  gsb_real_cunit__gsb_real_normalize))
     || (NULL == CU_add_test(pSuite, "of gsb_real_add()",               gsb_real_cunit__gsb_real_add))
     || (NULL == CU_add_test(pSuite, "of gsb_real_sub()",               gsb_real_cunit__gsb_real_sub))
+    || (NULL == CU_add_test(pSuite, "of gsb_real_mul()",               gsb_real_cunit__gsb_real_mul))
        )
         return NULL;
 



More information about the cvs mailing list