[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