* src/engine/gnc-numeric. -- fix the gnc_numeric_lcd() algo to

actually work with numbers that are not co-divisible but have
	  multiple-powers of co-factors.  For example, the old algorithm
	  thought the LCM of 100,96875 was 3100, when it is really 387500,
	  because it was removing the factor of '5' too many times..


git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@7864 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Derek Atkins 2003-01-21 01:50:16 +00:00
parent 5143d67952
commit dbe33ca873
2 changed files with 20 additions and 6 deletions

View File

@ -5,6 +5,12 @@
So, let's use g_list_prepend() and g_list_reverse() to speed
up the process significantly.
* src/engine/gnc-numeric. -- fix the gnc_numeric_lcd() algo to
actually work with numbers that are not co-divisible but have
multiple-powers of co-factors. For example, the old algorithm
thought the LCM of 100,96875 was 3100, when it is really 387500,
because it was removing the factor of '5' too many times..
2003-01-19 John Pierce <john@killterm.org>
* doc/Makefile.am

View File

@ -700,15 +700,22 @@ gnc_numeric_lcd(gnc_numeric a, gnc_numeric b) {
max_square = small_denom;
/* the LCM algorithm : take the union of the prime factors of the
* two args and multiply them together. To do this, we find the
* successive prime factors of the smaller denominator and eliminate
* them from the larger denominator, then multiply the smaller by
* the remains of the larger. */
/* the LCM algorithm : factor out the union of the prime factors of the
* two args and then multiply the remainders together.
*
* To do this, we find the successive prime factors of the smaller
* denominator and eliminate them from both the smaller and larger
* denominator (so we only count factors on a one-on-one basis),
* then multiply the original smaller by the remains of the larger.
*
* I.e. LCM 100,96875 == 2*2*5*5,31*5*5*5*5 = 2*2,31*5*5
* answer: multiply 100 by 31*5*5 == 387500
*/
while(current_divisor * current_divisor <= max_square) {
if(((small_denom % current_divisor) == 0) &&
((big_denom % current_divisor) == 0)) {
big_denom = big_denom / current_divisor;
small_denom = small_denom / current_divisor;
}
else {
if(current_divisor == 2) {
@ -730,7 +737,8 @@ gnc_numeric_lcd(gnc_numeric a, gnc_numeric b) {
}
}
return small_denom * big_denom;
/* max_sqaure is the original small_denom */
return max_square * big_denom;
}