473,770 Members | 4,558 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

How to write a small graceful gcd function?

My small function works, but I have some questions. And I want to
listen to you on How it is implemented?

1. The function does not check if parameter x is larger or smaller than
parameter y.

2. Is it better to use unsigned int or unsigned long as the type of
parameters x and y? This change may remove the if statement.

More comments are still welcome.

/*The Greatest Common Divisor, GCD for short, of two positive integers
can be computed with Euclid's division algorithm. Let the given numbers
be a and b, a >= b. Euclid's division algorithm has the following
steps:
1. Compute the remainder c of dividing a by b.
2. If the remainder c is zero, b is the greatest common divisor.
3. If c is not zero, replace a with b and b with the remainder c. Go
back to step (1).

http://www.cs.mtu.edu/~shene/COURSES...hap04/gcd.html */

/*computes the GCD (Greatest Common Divisor) of positive integers x and
y with Euclid's algorithm. return the GCD, or -1 for failure. - jhl,
Jul 2006*/

int gcd(int x, int y){
if (x 0 && y 0){
while (x % y){
y = x + y;
x = y - x;
y = (y - x) % x;
}
} else {
y = -1; /*input invalid*/
}
return y;
}

lovecreatesbeau ty

Jul 15 '06 #1
74 7484
Hi,
/*The Greatest Common Divisor, GCD for short, of two positive integers
can be computed with Euclid's division algorithm. Let the given numbers
be a and b, a >= b. Euclid's division algorithm has the following
steps:
1. Compute the remainder c of dividing a by b.
2. If the remainder c is zero, b is the greatest common divisor.
3. If c is not zero, replace a with b and b with the remainder c. Go
back to step (1).
int gcd (unsigned int a, unsigned int b)
{
unsigned int c;

if ( !a && !b )
return -1;

if (a b)
{
c = a;
a = b;
b = c;
}
while( (c=a%b) 0 )
{
a = b;
b = c;
}
return b;
}

Similar code in fortran is also available on the link u gave but I
could not understand why you have done this:
y = x + y;
x = y - x;
y = (y - x) % x;
Regards,

Nabeel Shaheen

lovecreatesbeau ty wrote:
My small function works, but I have some questions. And I want to
listen to you on How it is implemented?

1. The function does not check if parameter x is larger or smaller than
parameter y.

2. Is it better to use unsigned int or unsigned long as the type of
parameters x and y? This change may remove the if statement.

More comments are still welcome.

/*The Greatest Common Divisor, GCD for short, of two positive integers
can be computed with Euclid's division algorithm. Let the given numbers
be a and b, a >= b. Euclid's division algorithm has the following
steps:
1. Compute the remainder c of dividing a by b.
2. If the remainder c is zero, b is the greatest common divisor.
3. If c is not zero, replace a with b and b with the remainder c. Go
back to step (1).

http://www.cs.mtu.edu/~shene/COURSES...hap04/gcd.html */

/*computes the GCD (Greatest Common Divisor) of positive integers x and
y with Euclid's algorithm. return the GCD, or -1 for failure. - jhl,
Jul 2006*/

int gcd(int x, int y){
if (x 0 && y 0){
while (x % y){
y = x + y;
x = y - x;
y = (y - x) % x;
}
} else {
y = -1; /*input invalid*/
}
return y;
}

lovecreatesbeau ty
Jul 15 '06 #2
lovecreatesbeau ty wrote:
My small function works, but I have some questions. And I want to
listen to you on How it is implemented?

1. The function does not check if parameter x is larger or smaller than
parameter y.

2. Is it better to use unsigned int or unsigned long as the type of
parameters x and y? This change may remove the if statement.

More comments are still welcome.

/*The Greatest Common Divisor, GCD for short, of two positive integers
can be computed with Euclid's division algorithm. Let the given numbers
be a and b, a >= b. Euclid's division algorithm has the following
steps:
1. Compute the remainder c of dividing a by b.
2. If the remainder c is zero, b is the greatest common divisor.
3. If c is not zero, replace a with b and b with the remainder c. Go
back to step (1).

http://www.cs.mtu.edu/~shene/COURSES...hap04/gcd.html */

/*computes the GCD (Greatest Common Divisor) of positive integers x and
y with Euclid's algorithm. return the GCD, or -1 for failure. - jhl,
Jul 2006*/

int gcd(int x, int y){
if (x 0 && y 0){
while (x % y){
y = x + y;
x = y - x;
y = (y - x) % x;
}
} else {
y = -1; /*input invalid*/
}
return y;
}

lovecreatesbeau ty
int gcd( int m, int n ) // recursive
{
if(n==0) { return m; }
else
{ int answer = gcd(n,m%n);
return answer; }
}


--
Julian V. Noble
Professor Emeritus of Physics
University of Virginia
Jul 15 '06 #3
"Julian V. Noble" <jv*@virginia.e duwrites:
[...]
int gcd( int m, int n ) // recursive
{
if(n==0) { return m; }
else
{ int answer = gcd(n,m%n);
return answer; }
}
The temporary is unnecessary, and the formatting is just odd. Here's
how I'd write it:

int gcd(int m, int n)
{
if (n == 0) {
return m;
}
else {
return gcd(n, m % n);
}
}

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jul 15 '06 #4

Keith Thompson wrote:
"Julian V. Noble" <jv*@virginia.e duwrites:
[...]
int gcd( int m, int n ) // recursive
{
if(n==0) { return m; }
else
{ int answer = gcd(n,m%n);
return answer; }
}

The temporary is unnecessary, and the formatting is just odd. Here's
how I'd write it:

int gcd(int m, int n)
{
if (n == 0) {
return m;
}
else {
return gcd(n, m % n);
}
}
Thanks.

The function accepts zeros and negative integers as their arguments.
How are users without much mathematical knowledge like me supposed to
provide correct input to use it?

If compare an integer with zero value, will the following changes be
better?

1.

/*...*/ /*some necessary check*/

if (!n) {
return m;
} else {
return gcd(n, m % n);
}

2.

/*...*/ /*some necessary check*/

if (n) {
return gcd(n, m % n);
} else {
return m;
}

lovecreatesbeau ty

Jul 15 '06 #5
"lovecreatesbea uty" <lo************ ***@gmail.comwr ites:
Keith Thompson wrote:
>"Julian V. Noble" <jv*@virginia.e duwrites:
[...]
int gcd( int m, int n ) // recursive
{
if(n==0) { return m; }
else
{ int answer = gcd(n,m%n);
return answer; }
}

The temporary is unnecessary, and the formatting is just odd. Here's
how I'd write it:

int gcd(int m, int n)
{
if (n == 0) {
return m;
}
else {
return gcd(n, m % n);
}
}

Thanks.

The function accepts zeros and negative integers as their arguments.
How are users without much mathematical knowledge like me supposed to
provide correct input to use it?
The obvious solution to that is to change the arguments and result
from int to unsigned.

Different mathematical functions have different domains and ranges
(values that make sense for arguments and results). C, unlike some
other languages, doesn't let you declare a type with a specified range
of values -- but in this case, unsigned happens to be just what you
want.
If compare an integer with zero value, will the following changes be
better?

1.

/*...*/ /*some necessary check*/

if (!n) {
return m;
} else {
return gcd(n, m % n);
}

2.

/*...*/ /*some necessary check*/

if (n) {
return gcd(n, m % n);
} else {
return m;
}
In my opinion, not at all. Using "if (n)" or "if (!n)" makes sense if
n is a condition, something that can be logically true or false.
Here, n is a numeric value; comparing it to 0 isn't checking whether
it's true or false, it's just comparing it to 0.

It means exactly the same thing to the compiler, of course, but
clarity for the human reader is just as important.

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jul 15 '06 #6
Keith Thompson wrote:
"lovecreatesbea uty" <lo************ ***@gmail.comwr ites:
Keith Thompson wrote:
"Julian V. Noble" <jv*@virginia.e duwrites:
[...]
int gcd( int m, int n ) // recursive
{
if(n==0) { return m; }
else
{ int answer = gcd(n,m%n);
return answer; }
}

The temporary is unnecessary, and the formatting is just odd. Here's
how I'd write it:

int gcd(int m, int n)
{
if (n == 0) {
return m;
}
else {
return gcd(n, m % n);
}
}
Thanks.

The function accepts zeros and negative integers as their arguments.
How are users without much mathematical knowledge like me supposed to
provide correct input to use it?

The obvious solution to that is to change the arguments and result
from int to unsigned.

Different mathematical functions have different domains and ranges
(values that make sense for arguments and results). C, unlike some
other languages, doesn't let you declare a type with a specified range
of values -- but in this case, unsigned happens to be just what you
want.
The recursive way becomes the worst one and can not be improved to add
more parameter validation to it. If the function accepts input from
other automatic software systems, then someone should still keep an eye
on it, because the result may be wrong without warning.

int gcd(int x, int y){
if (x 0 && y 0){
while (x % y){
y = x + y;
x = y - x;
y = (y - x) % x;
}
} else {
y = -1; /*input invalid*/
}
return y;
}

int gcd3(int m, int n){
if (n == 0){
return m;
} else {
return gcd3(n, m % n);
}
}

$ ./a.out
gcd(8, 8): 8
gcd3(8, 8): 8
$ ./a.out
gcd(0, 8): -1
gcd3(0, 8): 8
$ ./a.out
gcd(8, 0): -1
gcd3(8, 0): 8
$

lovecreatesbeau ty

Jul 16 '06 #7
/*
The small and graceful versions are not as robust as those that
use a bit more code and also perform some sanity checks.
IMO-YMMV.
*/
/*
recursive variants:
*/
/* Recursive, using Knuth's subtraction trick: */
int gcd(int a, int b)
{
return a == b ? a : a b ? gcd(b, a - b) : gcd(b, b - a);
}
/* Recursive via simplest definition: */
int gcd(int a, int b)
{
return b ? gcd(b, a % b) : a;
}
/* Slight variant of one directly above: */
int gcd(int a, int b)
{
if (!b)
return a;
return gcd(b, a % b);
}

/*
Iterative variants:
*/
/* Iterative version with Knuth's subtraction method: */
int gcd(int a, int b)
{
while (a) {
if (a < b) {
int t = a;
a = b;
b = t;
}
a = a - b;
}
return b;
}
/* Iterative via fundamental definition: */
int gcd(int a, int b)
{
while (b) {
int t = b;
b = a % b;
a = t;
}
return a;
}
/* Not quite as safe as version directly above this one: */
int gcd(int a, int b)
{
do {
int r = a % b;
a = b;
b = r;
} while (b);
return a;
}
/* Sanity checks tossed in (a good idea): */
int gcd(int a, int b)
{
int t;
if (a < b)
t = a;
else
t = b;
while (a % t || b % t)
t = t - 1;
return t;
}

/*
With a few tricks and using a bigger type:
*/
/*************** *************** *************** **********/
/* This function uses the Euclidean Algorithm to */
/* calculate the greatest common divisor of two long */
/* double floating point numbers. */
/*************** *************** *************** **********/
/* Programmer: Danniel R. Corbit */
/* */
/* Copyright (C) 1992 by Danniel R. Corbit */
/* All rights reserved. */
/*************** *************** *************** **********/
/* Reference: "Factorizat ion and Primality Testing", */
/* by David M. Bressoud, */
/* Springer-Verlag 1989. */
/* pages 7-12. */
/*************** *************** *************** **********/
#include <math.h>
long double ldGcd(long double a, long double b)
{
int shiftcount = 0;
long double tmp;
int i;
/*************** *************** *************** *************** *******/
/* This zero testing stuff may seem odd, since zero is not likely. */
/* However, knowing that neither a nor b is zero will speed up */
/* later operations greatly by elimination of tests for zero. */
/*************** *************** *************** *************** *******/
if (a == 0.0e0L)
{
tmp = b;
}
else if (b == 0.0e0L)
{
tmp = a;
}
else /* Neither a NOR b is zero! */
{
/* Absolute values used. */
a = a 0.0e0L ? a : -a;
b = b 0.0e0L ? b : -b;

/*************** *************** *************** *************** **/
/* While all this fuss about numbers divisible by 2 may seem */
/* like quite a bother, half of the integers in the universe */
/* are evenly divisible by 2. Hence, on a random sample of */
/* input values, great benefit will be realized. The odds */
/* that at least one of a,b is even is 1 - (1/2)*(1/2) = .75 */
/* since the probability that both are odd is .25. */
/*************** *************** *************** *************** **/
/* If a & b are divisible by 2, gcd(a,b) = 2*gcd(a/2,b/2). */
/*************** *************** *************** *************** **/
while (fmodl(a,2.0e0L ) == 0.0e0L && fmodl(b,2.0e0L) == 0.0e0L)
{
a /= 2.0e0L;
b /= 2.0e0L;
shiftcount++;
}

/*************** *************** *************** *************** **/
/* If the a is divisible by 2 and b is not divisible by 2, */
/* then gcd(a,b) = gcd(a/2,b). */
/*************** *************** *************** *************** **/
while (fmodl(a,2.0e0L ) == 0.0e0L)
{
a /= 2.0e0L;
}

/*************** *************** *************** **********/
/* If b is divisible by 2 and a is not divisible by 2, */
/* then gcd(a,b) = gcd(a,b/2). */
/*************** *************** *************** **********/
while (fmodl(b,2.0e0L ) == 0.0e0L)
{
b /= 2.0e0L;
}

/*************** *************** *************** *************** **********/
/* Make sure the numbers are in the proper order (swap if necessary).
*/
/*************** *************** *************** *************** **********/
if (b a)
{
tmp = a;
a = b;
b = tmp;
}

/*************** *************** **********/
/* Euclid's famous gcd algorithm: */
/* Iterate until the remainder is <= 1. */
/*************** *************** **********/
while (b 1.0e0L)
{
tmp = b;
b = fmodl(a,b);
a = tmp;
}
if (b == 0.0e0L)
tmp = a;
else
tmp = b;

/*************** *************** *************** *************** ***********/
/* If we divided BOTH numbers by factors of 2, we must compensate now.
*/
/*************** *************** *************** *************** ***********/
if (shiftcount 0 && tmp 0.0e0L)
for (i = 0; i < shiftcount; i++)
tmp += tmp;
}
return (tmp);
}
Jul 17 '06 #8

lovecreatesbeau ty wrote:
My small function works, but I have some questions. And I want to
listen to you on How it is implemented?
Divisions are for chumps...

unsigned gcd(unsigned a, unsigned b)
{
unsigned k, t;

k = 0;
while (!(a & 1 || b & 1)) {
++k; a >>= 1; b >>= 1;
}
while (!(a & 1)) { a >>= 1; }
while (!(b & 1)) { b >>= 1; }

while (b) {
if (a b) { t = a; a = b; b = t; }
b = b - a;
while (!(b & 1)) { b >>= 1; }
}
return a << k;
}

:-)

[untested, from memory, from my book too...]

Tom

Jul 17 '06 #9
Dann Corbit wrote:
I guess that most of the time repeated subtraction will not be faster than
division with modern processors. I do like this implementation, though.
Of course, it assumes 2's complement machines, but that is pretty much a
forgone conclusion now-days.
if b a and b has k bits then you loop at most k times [hint: b - a is
always either even or zero]

So are 16, 32 or 64 subtractions/shifts faster than a small set of
divisions? Most likely yes, specially on things like an ARM. It
really depends on the numbers and the platform.

Also my code doesn't link in the division support [for processors that
lack a divider] so it's a bit more compact. It's also Kernel save
[using divisions in the Kernel last I heard was a no no].

Tom

Jul 17 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
1575
by: tings | last post by:
How to write such a function that can take varible number and tyoes of arguments, like printf("... %d, %s...", myInt, myString...)? Thanks for for your help!
3
1960
by: Wen | last post by:
hello, now, i wanna port a c++ program into C# project. a DLL written by C++ and keep it no change, and UI wirtten by C#. my C++ UI code is as below: // error handlers --global function callback function // C++ dll would invoke this function if needed void ImageConv_Callback_Handler(const char *szInfo) {
3
2722
by: datttanand | last post by:
How to write the main function in java script? such as in vb script sub main end sub
1
2152
by: rasmidas | last post by:
I have a function sEntityFree() which is a function from a third party S/w we are using. For this we have our enhanced code. sEntityFree() has been called inside our enhanced code 2000 or 3000 times. But NULL pointer checking before freeing the memory is not there. Like the function has been called as below: sEntityFree(Entity, ( void** )&StructPtr, sYES ); or sEntityFree(Entity, ( void** )&StructPtr, sNO ); If I will write it...
0
1442
by: nabil035 | last post by:
I explain exactly what I want to do: write a callback function in a C++/CLI application this application imports function from a native DLL call this function from the DLL and return the results to the application Can Anyone help with the simplest example, please!
7
1507
by: mynkow | last post by:
Hi, I want to write an universal function called isNegative( param ) where the param can be float, int, double, long etc. The result will be true/false. Any comments?
0
9602
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10237
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10017
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9882
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
7431
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6690
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5326
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
3987
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3589
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.