473,785 Members | 2,425 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
74 7485
"Dann Corbit" <dc*****@connx. comwrites:
/*
Now that I actually understand how it works, I like the subtraction trick a
lot better. In this instance, (lots of small repeated factors) it takes the
same number of iterations as the modulo version
*/
Are we talking about the same binary GCD algorithm that's in
Knuth? There's a wikipedia page about it:
http://en.wikipedia.org/wiki/Binary_GCD_algorithm

(Every algorithm is in Knuth if you look hard enough.)
--
int main(void){char p[]="ABCDEFGHIJKLM NOPQRSTUVWXYZab cdefghijklmnopq rstuvwxyz.\
\n",*q="kl BIcNBFr.NKEzjwC IxNJC";int i=sizeof p/2;char *strchr();int putchar(\
);while(*q){i+= strchr(p,*q++)-p;if(i>=(int)si zeof p)i-=sizeof p-1;putchar(p[i]\
);}return 0;}
Jul 17 '06 #21
"Ben Pfaff" <bl*@cs.stanfor d.eduwrote in message
news:87******** ****@benpfaff.o rg...
"Dann Corbit" <dc*****@connx. comwrites:
>/*
Now that I actually understand how it works, I like the subtraction trick
a
lot better. In this instance, (lots of small repeated factors) it takes
the
same number of iterations as the modulo version
*/

Are we talking about the same binary GCD algorithm that's in
Knuth? There's a wikipedia page about it:
http://en.wikipedia.org/wiki/Binary_GCD_algorithm

(Every algorithm is in Knuth if you look hard enough.)
He wasn't aware of using a priority queue to do a merge. I sent him some
email about it a long time ago. Lots better than the snowplow.
--
int main(void){char
p[]="ABCDEFGHIJKLM NOPQRSTUVWXYZab cdefghijklmnopq rstuvwxyz.\
\n",*q="kl BIcNBFr.NKEzjwC IxNJC";int i=sizeof p/2;char *strchr();int
putchar(\
);while(*q){i+= strchr(p,*q++)-p;if(i>=(int)si zeof p)i-=sizeof
p-1;putchar(p[i]\
);}return 0;}

Jul 17 '06 #22
Ben Pfaff wrote:
Are we talking about the same binary GCD algorithm that's in
Knuth? There's a wikipedia page about it:
http://en.wikipedia.org/wiki/Binary_GCD_algorithm

(Every algorithm is in Knuth if you look hard enough.)
Hmm, lots of them are, but not all. Specially when you start moving
off into more crypto like problems [e.g. elliptic curves, real
exponentiation[*]]. Also he misses a lot more practical stuff than
you'd think. If we all implemented multiplication by his book we
wouldn't be using comba techniques for instance.
[*] I realize he talks about addition chains but I don't recall how
much he talks about sliding windows for instance.

Definitely worth having them. I bought the entire set when I was still
in high scool. Served me well through college and afterwards so far.

Tom

Jul 17 '06 #23
"Tom St Denis" <to********@gma il.comwrote in message
news:11******** *************@m 73g2000cwd.goog legroups.com...
Dann Corbit wrote:
>How can the division way be quadratic? It takes out repeated factors in
every iteration. The above example takes 2 modulus cycles.

You assume division is atomic and equivalent to subtraction?

... really?
On modern CPUs in hardware, it is. Modulus will be slower by a small,
constant factor. Since the algorithm itself has the same performance, and
since the loop does not execute very many times, I guess that the difference
will be very small.
Try saying that for 1000 it numbers.
I guess that you mean for 1000 digit numbers. If you have to emulate the
math in software, it might be a significant difference.
Tom

Jul 17 '06 #24

Dann Corbit wrote:
"Tom St Denis" <to********@gma il.comwrote in message
news:11******** *************@m 73g2000cwd.goog legroups.com...
Dann Corbit wrote:
How can the division way be quadratic? It takes out repeated factors in
every iteration. The above example takes 2 modulus cycles.
You assume division is atomic and equivalent to subtraction?

... really?

On modern CPUs in hardware, it is. Modulus will be slower by a small,
constant factor. Since the algorithm itself has the same performance, and
since the loop does not execute very many times, I guess that the difference
will be very small.
First off, that's not even remotely true. Division is a LOT slower
than subtraction. Or put it another way, if they took the same number
of cycles you'd be looking at a 37MHz processor.

Second, division is often dozens if not hundreds of cycles.

Third, most processors don't even have division opcodes [mips, ARM, PPC
anyone?]
Try saying that for 1000 it numbers.

I guess that you mean for 1000 digit numbers. If you have to emulate the
math in software, it might be a significant difference.
digit bit whatever.

Division is normally quadratic unless you start getting fancy with the
Karatsuba.

Since division is quadratic, doing gcd with it is also quadratic.
think about it.

Division: O(n^2)

GCD: O(cn^2) for any [say] small c

What does the O() of GCD reduce to?

Subtraction is fully linear O(n). So GCD == O(cn) means it's also
linear.

*In practice* for small numbers they may act comparably. Specially if
a mod b is small. Which is why it's not entirely a bad approach.

For small types, unless you can prove otherwise it's usually best to
use the binary approach. It's more "portable" [in that you don't need
division] and usually just as fast[*]

Tom
[*] in fact it's guaranteed to be no slower on platforms without a
division opcode.

Jul 17 '06 #25
In article <11************ **********@p79g 2000cwp.googleg roups.com>,
Tom St Denis <to********@gma il.comwrote:
>Third, most processors don't even have division opcodes [mips, ARM, PPC
anyone?]
The original MIPS design did not have division, but division was
provided right from the first commercial offering, the R2000.

It could be that there is no division in some of the processors aimed
at the embedded market; I'm only familiar with the MIPS general purpose
chips.
--
"It is important to remember that when it comes to law, computers
never make copies, only human beings make copies. Computers are given
commands, not permission. Only people can be given permission."
-- Brad Templeton
Jul 17 '06 #26
Walter Roberson wrote:
The original MIPS design did not have division, but division was
provided right from the first commercial offering, the R2000.

It could be that there is no division in some of the processors aimed
at the embedded market; I'm only familiar with the MIPS general purpose
chips.
And likely it's not one cycle right?

Kinda violates the MIPS RISC principles ...

Of course, if they could add a divider why can't they add an "add with
carry" hehehehe...

Though the 4Km series is nice in that regard.

tom

Jul 17 '06 #27
"Tom St Denis" <to********@gma il.comwrote in message
news:11******** **************@ p79g2000cwp.goo glegroups.com.. .
>
Dann Corbit wrote:
>"Tom St Denis" <to********@gma il.comwrote in message
news:11******* **************@ m73g2000cwd.goo glegroups.com.. .
Dann Corbit wrote:
How can the division way be quadratic? It takes out repeated factors
in
every iteration. The above example takes 2 modulus cycles.

You assume division is atomic and equivalent to subtraction?

... really?

On modern CPUs in hardware, it is. Modulus will be slower by a small,
constant factor. Since the algorithm itself has the same performance,
and
since the loop does not execute very many times, I guess that the
difference
will be very small.

First off, that's not even remotely true. Division is a LOT slower
than subtraction. Or put it another way, if they took the same number
of cycles you'd be looking at a 37MHz processor.

Second, division is often dozens if not hundreds of cycles.

Third, most processors don't even have division opcodes [mips, ARM, PPC
anyone?]
Try saying that for 1000 it numbers.

I guess that you mean for 1000 digit numbers. If you have to emulate the
math in software, it might be a significant difference.

digit bit whatever.

Division is normally quadratic unless you start getting fancy with the
Karatsuba.

Since division is quadratic, doing gcd with it is also quadratic.
think about it.
Division is not quadratic in hardware.
It will take a definite, fixed number of cycles at most. (17 for a 64 bit
AMD CPU, IIRC).

Subtraction will be faster, but only by a small, fixed constant.

If your hardware does not support division, then the subtraction method
would be a significant advantage.
Division: O(n^2)

GCD: O(cn^2) for any [say] small c

What does the O() of GCD reduce to?

Subtraction is fully linear O(n). So GCD == O(cn) means it's also
linear.

*In practice* for small numbers they may act comparably. Specially if
a mod b is small. Which is why it's not entirely a bad approach.

For small types, unless you can prove otherwise it's usually best to
use the binary approach. It's more "portable" [in that you don't need
division] and usually just as fast[*]

Tom
[*] in fact it's guaranteed to be no slower on platforms without a
division opcode.
/*
Now that I actually understand how it works, I like the subtraction trick a
lot better. In this instance, (lots of small repeated factors) it takes the
same number of iterations as the modulo version
*/
unsigned long long modulos = 0;
unsigned long long subtractions = 0;
unsigned long long gcdm(unsigned long long a, unsigned long long b)
{
unsigned long long 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;
modulos++;
while (b && !(b & 1)) { b >>= 1; }
}
return a << k;
}
unsigned long long gcds(unsigned long long a, unsigned long long b)
{
unsigned long long 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;
subtractions++;
while (b && !(b & 1)) { b >>= 1; }
}
return a << k;
}
unsigned long long big=12974633789 0625;
unsigned long long med=86497558593 75*7;

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
unsigned long long randvals[1000000];
int main(void)
{
clock_t start;
clock_t end;
unsigned long long answer=0;
size_t index;
for (index = 0; index < 1000000; index++)
{
randvals[index] = rand();
randvals[index] <<= 32;
randvals[index] += rand();
}
start = clock();
for (index = 0; index < 1000000-1; index++)
answer += gcdm(randvals[index],randvals[index+1]);
end = clock();
printf("clocks to do one million modular gcd's = %u\n", (unsigned)
end-start) ;
answer = 0;
start = clock();
for (index = 0; index < 1000000-1; index++)
answer += gcds(randvals[index],randvals[index+1]);
end = clock();
printf("clocks to do one million subtraction gcd's = %u\n", (unsigned)
end-start) ;
return 0;
}

/*
clocks to do one million modular gcd's = 1031
clocks to do one million subtraction gcd's = 703
Press any key to continue . . .
*/
Jul 17 '06 #28
Dann Corbit wrote:
Since division is quadratic, doing gcd with it is also quadratic.
think about it.

Division is not quadratic in hardware.
It will take a definite, fixed number of cycles at most. (17 for a 64 bit
AMD CPU, IIRC).
Actually you're still wrong. It's either quadratic in time or space
[or both]. You can make it O(1) time by taking O(n^2) space but that's
still "quadratic" . You linearize it by taking linear space O(n) for
O(n) which is NOT quadratic [just not practical for the size of numbers
you work with in processors] by using interpolation [e.g. Karatsuba]

hint: Why do you think multipliers are fast. It isn't because they
violated the O(n^2) rule. It's because the multipliers are big[*].
They take up nearly O(n^2) space to do the multiplication in a trivial
amount of time.
Subtraction will be faster, but only by a small, fixed constant.

If your hardware does not support division, then the subtraction method
would be a significant advantage.
Or if you have to work with larger numbers. Even with an O(1) division
opcode, the division of n-digit numbers is O(n^2) time. So even if
divide == sub for time on a single digit it'd be slower for larger
numbers [proof: division by shift/subtract is slower than a single
subtraction].

Tom
[*] Some processors use a Karatsuba trick but so far I haven't heard of
any x86 series using it as a fact....

Jul 17 '06 #29
"Ben Pfaff" <bl*@cs.stanfor d.eduwrote in message
news:87******** ****@benpfaff.o rg...
"Dann Corbit" <dc*****@connx. comwrites:
>/*
Now that I actually understand how it works, I like the subtraction trick
a
lot better. In this instance, (lots of small repeated factors) it takes
the
same number of iterations as the modulo version
*/

Are we talking about the same binary GCD algorithm that's in
Knuth? There's a wikipedia page about it:
http://en.wikipedia.org/wiki/Binary_GCD_algorithm

(Every algorithm is in Knuth if you look hard enough.)
Tom's version seems somewhat faster than the web article version.
The timings below are after profile guided optimization.

/*
Now that I actually understand how it works, I like the subtraction trick a
lot better. In this instance, (lots of small repeated factors) it takes the
same number of iterations as the modulo version
*/
unsigned long long modulos = 0;
unsigned long long subtractions = 0;
unsigned long long gcdm(unsigned long long a, unsigned long long b)
{
unsigned long long 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 && !(b & 1)) { b >>= 1; }
}
return a << k;
}
unsigned long long gcds(unsigned long long a, unsigned long long b)
{
unsigned long long 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 && !(b & 1)) { b >>= 1; }
}
return a << k;
}

unsigned long long gcd(unsigned long long u, unsigned long long v) {
unsigned long long k = 0;
if (u == 0)
return v;
if (v == 0)
return u;
while ((u & 1) == 0 && (v & 1) == 0) { /* while both u and v are even
*/
u >>= 1; /* shift u right, dividing it by 2 */
v >>= 1; /* shift v right, dividing it by 2 */
k++; /* add a power of 2 to the final result */
}
/* At this point either u or v (or both) is odd */
do {
if ((u & 1) == 0) /* if u is even */
u >>= 1; /* divide u by 2 */
else if ((v & 1) == 0) /* else if v is even */
v >>= 1; /* divide v by 2 */
else if (u >= v) /* u and v are both odd */
u = (u-v) >1;
else /* u and v both odd, v u */
v = (v-u) >1;
} while (u 0);
return v << k; /* returns v * 2^k */
}

unsigned long long big=12974633789 0625;
unsigned long long med=86497558593 75*7;

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
unsigned long long randvals[1000000];
int main(void)
{
clock_t start;
clock_t end;
unsigned long long answer=0;
size_t index;
for (index = 0; index < 1000000; index++)
{
randvals[index] = rand();
randvals[index] <<= 32;
randvals[index] += rand();
}
start = clock();
for (index = 0; index < 1000000-1; index++)
answer += gcdm(randvals[index],randvals[index+1]);
end = clock();
printf("clocks to do one million modular gcd's = %u, summed GCD =
%llu\n", (unsigned) end-start, answer) ;
answer = 0;
start = clock();
for (index = 0; index < 1000000-1; index++)
answer += gcds(randvals[index],randvals[index+1]);
end = clock();
printf("clocks to do one million subtraction gcd's = %u, summed GCD =
%llu\n", (unsigned) end-start, answer) ;
answer = 0;
start = clock();
for (index = 0; index < 1000000-1; index++)
answer += gcd(randvals[index],randvals[index+1]);
end = clock();
printf("clocks to do one million subtraction gcd's {web article version} =
%u, summed GCD = %llu\n", (unsigned) end-start, answer) ;
return 0;
}

/*
clocks to do one million modular gcd's = 1031, summed GCD = 9203554
clocks to do one million subtraction gcd's = 766, summed GCD = 9203554
clocks to do one million subtraction gcd's {web article version} = 1109,
summed GCD = 9203554
Press any key to continue . . .

*/

--
int main(void){char
p[]="ABCDEFGHIJKLM NOPQRSTUVWXYZab cdefghijklmnopq rstuvwxyz.\
\n",*q="kl BIcNBFr.NKEzjwC IxNJC";int i=sizeof p/2;char *strchr();int
putchar(\
);while(*q){i+= strchr(p,*q++)-p;if(i>=(int)si zeof p)i-=sizeof
p-1;putchar(p[i]\
);}return 0;}

Jul 17 '06 #30

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
9646
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...
1
10096
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
8982
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7504
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
6742
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
5386
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...
0
5514
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
3658
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2887
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.