PHWinfo banniere

Titres
PORTAIL ANNUAIRE ARTICLES COMPARATEUR HÉBERGEURS DEVIS FORUMS RÉDUCTEUR D'URL
Précédent   PHWinfo > Autres forums > Forum Programmation & Conception > comp.lang.cplus > Is there an algorithm for integer multiply and divide at the same time?
S'inscrire FAQ Membres Recherche Messages du jour Marquer les forums comme lus
Is there an algorithm for integer multiply and divide at the same time?

Réponse
 
LinkBack Outils de la discussion
Vieux 02/07/2008, 02h49   #1
Default User
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Is there an algorithm for integer multiply and divide at the same time?

Hi,

If I have three 64 bit integers and I want to do this operation on them:

x*y/z

Lets say that what we are multiplying by (y) is offset by what we are
dividing by (z) so that the final answer will fit in a 64-bit integer.

Let me simplify it by using unsigned chars (8 bits):

254*253/252 = 255

But, if we only had 8 bit integers to work with, is there an algorithm that
would use 8 bit integers only to come up with the right answer of 255 ? The
obvious problem is that the multiplication yields a number much larger than
an 8-bit integer.

Where I am going with this is that sometimes I need to multiply and divide
large 64-bit integers and as long as the resulting number fits in a 64-bit
integer, can I do this with 64-bit integers alone?

Thanks,

Alan
www.sadevelopment.com


  Réponse avec citation
Vieux 02/07/2008, 03h15   #2
Darío Griffo
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Is there an algorithm for integer multiply and divide at the sametime?

On Jul 1, 10:49 pm, "Default User" <nospam38...@forme.com> wrote:
> Hi,
>
> If I have three 64 bit integers and I want to do this operation on them:
>
> x*y/z
>
> But, if we only had 8 bit integers to work with, is there an algorithm that
> would use 8 bit integers only to come up with the right answer of 255 ? The
> obvious problem is that the multiplication yields a number much larger than
> an 8-bit integer.


I think this should work well

x*(y/z) or try this (x/z)*y

Darío
  Réponse avec citation
Vieux 02/07/2008, 03h29   #3
Kai-Uwe Bux
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Is there an algorithm for integer multiply and divide at the same time?

Default User wrote:

> Hi,
>
> If I have three 64 bit integers and I want to do this operation on them:
>
> x*y/z
>
> Lets say that what we are multiplying by (y) is offset by what we are
> dividing by (z) so that the final answer will fit in a 64-bit integer.
>
> Let me simplify it by using unsigned chars (8 bits):
>
> 254*253/252 = 255
>
> But, if we only had 8 bit integers to work with, is there an algorithm
> that
> would use 8 bit integers only to come up with the right answer of 255 ?
> The obvious problem is that the multiplication yields a number much larger
> than an 8-bit integer.
>
> Where I am going with this is that sometimes I need to multiply and divide
> large 64-bit integers and as long as the resulting number fits in a 64-bit
> integer, can I do this with 64-bit integers alone?


It might be easier (and maybe also more efficient) to use double or long
double for the computation and then case back (provided they have more than
64 bit mantissa on your target platform). However, there could be some
tricky analysis involved to prove the code correct.


Best

Kai-Uwe Bux
  Réponse avec citation
Vieux 02/07/2008, 10h34   #4
James Kanze
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Is there an algorithm for integer multiply and divide at the sametime?

On Jul 2, 4:29 am, Kai-Uwe Bux <jkherci...@gmx.net> wrote:
> Default User wrote:
> > If I have three 64 bit integers and I want to do this
> > operation on them:


> > x*y/z


> > Lets say that what we are multiplying by (y) is offset by
> > what we are dividing by (z) so that the final answer will
> > fit in a 64-bit integer.


> > Let me simplify it by using unsigned chars (8 bits):


> > 254*253/252 = 255


> > But, if we only had 8 bit integers to work with, is there an
> > algorithm that would use 8 bit integers only to come up with
> > the right answer of 255 ? The obvious problem is that the
> > multiplication yields a number much larger than an 8-bit
> > integer.


> > Where I am going with this is that sometimes I need to
> > multiply and divide large 64-bit integers and as long as the
> > resulting number fits in a 64-bit integer, can I do this
> > with 64-bit integers alone?


> It might be easier (and maybe also more efficient) to use
> double or long double for the computation and then case back
> (provided they have more than 64 bit mantissa on your target
> platform).


Do you know of such a platform? The intermediate value he's
concerned with can have up to 127 bits, so you'd need a mantissa
of 127 bits. I think some have existed (perhaps some of the old
CDC mainframes), but I don't know of any today.

> However, there could be some tricky analysis involved to prove
> the code correct.


*If* the conditions are exactly as he stated, then it's easy to
prove the code incorrect (and even find example values which
would fail a test) for IEEE double, or any representation which
uses less than 127 bits in the mantissa.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
  Réponse avec citation
Vieux 02/07/2008, 10h41   #5
Gernot Frisch
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Is there an algorithm for integer multiply and divide at the same time?



> Where I am going with this is that sometimes I need to multiply and divide
> large 64-bit integers and as long as the resulting number fits in a 64-bit
> integer, can I do this with 64-bit integers alone?


There's the MulDiv function from Windows, which is implemented in ReactOS
like:
http://www.reactos.org/generated/dox...8c-source.html


  Réponse avec citation
Vieux 02/07/2008, 11h33   #6
Kai-Uwe Bux
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Is there an algorithm for integer multiply and divide at the same time?

James Kanze wrote:

> On Jul 2, 4:29 am, Kai-Uwe Bux <jkherci...@gmx.net> wrote:
>> Default User wrote:
>> > If I have three 64 bit integers and I want to do this
>> > operation on them:

>
>> > x*y/z

>
>> > Lets say that what we are multiplying by (y) is offset by
>> > what we are dividing by (z) so that the final answer will
>> > fit in a 64-bit integer.

>
>> > Let me simplify it by using unsigned chars (8 bits):

>
>> > 254*253/252 = 255

>
>> > But, if we only had 8 bit integers to work with, is there an
>> > algorithm that would use 8 bit integers only to come up with
>> > the right answer of 255 ? The obvious problem is that the
>> > multiplication yields a number much larger than an 8-bit
>> > integer.

>
>> > Where I am going with this is that sometimes I need to
>> > multiply and divide large 64-bit integers and as long as the
>> > resulting number fits in a 64-bit integer, can I do this
>> > with 64-bit integers alone?

>
>> It might be easier (and maybe also more efficient) to use
>> double or long double for the computation and then case back
>> (provided they have more than 64 bit mantissa on your target
>> platform).

>
> Do you know of such a platform? The intermediate value he's
> concerned with can have up to 127 bits, so you'd need a mantissa
> of 127 bits. I think some have existed (perhaps some of the old
> CDC mainframes), but I don't know of any today.


I actually had thought about this before I posted, and you don't need 127
bits mantissa. However, in order to see that, we have to take the OP
serious on his claim that the result will fit into a 64 bit number. Let me
illustrate what happens with decimals. Suppose, we are dealing with 5-digit
decimals in the range [0,99999]. We want to compute a*b/c for such numbers
(truncated to the integral part). Let's assume we have the quotient b/c to
7 decimals (not 10!). Then, the product a*(b/c) is of one of the following
forms:

a * b/c

xxxxx * x.xxxxxx
0xxxx * xx.xxxxx
00xxx * xxx.xxxx
000xx * xxxx.xxx
0000x * xxxxx.xx

If the leading digits are any farther to the left, the product will exceed
10000.

Now observe that a change in the last digit of b/c changes the product
a*(b/c) less than 1. Therefore, it is not a priori hopeless to try to get
the integral part of a*(b/c) via this method. If we throw in one more digit
of precision, we can get within distance 0.1 of the product, which should
be good enough to determine the integral part. I did not carry out a
complete analysis; but based upon the above, I conjecture that a mantissa
of 68 bits will be enough (getting within distance 0.01(binary) of the
product).

Now, looking up floating point formats, I do realize that the OP might still
be out of luck. It appears that quadruple precision is needed.


>> However, there could be some tricky analysis involved to prove
>> the code correct.

>
> *If* the conditions are exactly as he stated, then it's easy to
> prove the code incorrect (and even find example values which
> would fail a test) for IEEE double, or any representation which
> uses less than 127 bits in the mantissa.


It's far from easy to prove incorrectness; it is also far from easy to prove
correctness, though. The heuristic above illustrates some of the
intricacies that one will run into.


Best

Kai-Uwe Bux
  Réponse avec citation
Vieux 02/07/2008, 13h37   #7
Default User
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Is there an algorithm for integer multiply and divide at the same time?

Hi,

> There's the MulDiv function from Windows, which is implemented in ReactOS
> http://www.reactos.org/generated/dox...8c-source.html



Thanks for the ideas guys, this is basically what I am looking for, but this
code counts on RtlEnlargedUnsignedDivide which in turn counts on
(ULONGLONG).

I realize there are bignum libraries out there, but I am really only looking
for a small single algorithm to do this. I will be dealing with integers
only, and in such a way that I balance the Numerator/Denominator so that I
know the result will fit properly.

In this case I am looking to make 64 bit integers perform 128 bit like
multiplication/division, but I would think I could easily adapt code
designed to make 32 bit integers perform 64 bit like
multiplication/division. Does anyone have any simple/short code made 64 bit
integers from 32 bit integers, from a time before 64 bit integers were
available natively in the compiler?

The calculations I am trying to perform can be done in double, but it is 150
times slower according to some testing I've done which is why I'd rather
stick to integers if I can.

Thanks,

Alan


  Réponse avec citation
Vieux 02/07/2008, 15h08   #8
James Kanze
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Is there an algorithm for integer multiply and divide at the sametime?

On Jul 2, 12:33 pm, Kai-Uwe Bux <jkherci...@gmx.net> wrote:
> James Kanze wrote:
> > On Jul 2, 4:29 am, Kai-Uwe Bux <jkherci...@gmx.net> wrote:
> >> Default User wrote:
> >> > If I have three 64 bit integers and I want to do this
> >> > operation on them:


> >> > x*y/z


> >> > Lets say that what we are multiplying by (y) is offset by
> >> > what we are dividing by (z) so that the final answer will
> >> > fit in a 64-bit integer.


> >> > Let me simplify it by using unsigned chars (8 bits):


> >> > 254*253/252 = 255


> >> > But, if we only had 8 bit integers to work with, is there an
> >> > algorithm that would use 8 bit integers only to come up with
> >> > the right answer of 255 ? The obvious problem is that the
> >> > multiplication yields a number much larger than an 8-bit
> >> > integer.


> >> > Where I am going with this is that sometimes I need to
> >> > multiply and divide large 64-bit integers and as long as the
> >> > resulting number fits in a 64-bit integer, can I do this
> >> > with 64-bit integers alone?


> >> It might be easier (and maybe also more efficient) to use
> >> double or long double for the computation and then case back
> >> (provided they have more than 64 bit mantissa on your target
> >> platform).


> > Do you know of such a platform? The intermediate value he's
> > concerned with can have up to 127 bits, so you'd need a mantissa
> > of 127 bits. I think some have existed (perhaps some of the old
> > CDC mainframes), but I don't know of any today.


> I actually had thought about this before I posted, and you
> don't need 127 bits mantissa. However, in order to see that,
> we have to take the OP serious on his claim that the result
> will fit into a 64 bit number. Let me illustrate what happens
> with decimals. Suppose, we are dealing with 5-digit decimals
> in the range [0,99999]. We want to compute a*b/c for such
> numbers (truncated to the integral part). Let's assume we have
> the quotient b/c to 7 decimals (not 10!). Then, the product
> a*(b/c) is of one of the following forms:


> a * b/c


> xxxxx * x.xxxxxx
> 0xxxx * xx.xxxxx
> 00xxx * xxx.xxxx
> 000xx * xxxx.xxx
> 0000x * xxxxx.xx


> If the leading digits are any farther to the left, the product
> will exceed 10000.


> Now observe that a change in the last digit of b/c changes the
> product a*(b/c) less than 1. Therefore, it is not a priori
> hopeless to try to get the integral part of a*(b/c) via this
> method. If we throw in one more digit of precision, we can get
> within distance 0.1 of the product, which should be good
> enough to determine the integral part. I did not carry out a
> complete analysis; but based upon the above, I conjecture that
> a mantissa of 68 bits will be enough (getting within distance
> 0.01(binary) of the product).


Unless, of course, there are some corner cases where the
rounding to the seven decimals after the division messes things
up.

> Now, looking up floating point formats, I do realize that the
> OP might still be out of luck. It appears that quadruple
> precision is needed.


Well, the Unisys MCP has a 96 bit long double, with
LDBL_MANT_DIG == 26 and FLT_RADIX == 8 (so a 78 bit mantissa).
On the other hand, I'd be rather surprised if that's the machine
he has on his desktop.

> >> However, there could be some tricky analysis involved to prove
> >> the code correct.


> > *If* the conditions are exactly as he stated, then it's easy
> > to prove the code incorrect (and even find example values
> > which would fail a test) for IEEE double, or any
> > representation which uses less than 127 bits in the
> > mantissa.


> It's far from easy to prove incorrectness; it is also far from
> easy to prove correctness, though. The heuristic above
> illustrates some of the intricacies that one will run into.


It's easy to prove incorrectness: just find an example that
doesn't work:-).

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
  Réponse avec citation
Vieux 02/07/2008, 15h16   #9
Kai-Uwe Bux
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Is there an algorithm for integer multiply and divide at the same time?

Default User wrote:

> Hi,
>
>> There's the MulDiv function from Windows, which is implemented in ReactOS
>> http://www.reactos.org/generated/dox...8c-source.html

>
>
> Thanks for the ideas guys, this is basically what I am looking for, but
> this code counts on RtlEnlargedUnsignedDivide which in turn counts on
> (ULONGLONG).
>
> I realize there are bignum libraries out there, but I am really only
> looking
> for a small single algorithm to do this. I will be dealing with integers
> only, and in such a way that I balance the Numerator/Denominator so that I
> know the result will fit properly.
>
> In this case I am looking to make 64 bit integers perform 128 bit like
> multiplication/division, but I would think I could easily adapt code
> designed to make 32 bit integers perform 64 bit like
> multiplication/division. Does anyone have any simple/short code made 64
> bit integers from 32 bit integers, from a time before 64 bit integers were
> available natively in the compiler?


Addition is easy.

Multiplication can be done like so: split the 64bit factors into high and
low unsinged longs of 32 bits. Then you have to compute

( a * 2^32 + b ) * ( c * 2^32 + d )
=
a*c *2^64
+
(a-b)*(d-c) *2^32
+
a*c *2^32
+
b*d *2^32
+
c*d;

which requires computing the three 64bit products ac, (a-b)(d-c), and cd.
The rest is bit shifting and addition (which we agreed is easy :-).

Alternatively, you could also do:

( a * 2^32 + b ) * ( c * 2^32 + d )
=
a*c *2^64
+
a*d *2^32
+
b*c *2^32
+
b*d

which requires computing four 64bit products but is slightly less demanding
on additions and bit shifting (also it does not involve dealing with
differences).

The tricky part is division. I have no idea how to do that efficiently.


> The calculations I am trying to perform can be done in double, but it is
> 150 times slower according to some testing I've done which is why I'd
> rather stick to integers if I can.


150 times slower compared to what? If you already have a solution that beats
floating point arithmetic by a factor of 150, you are probably all set and
it won't get any better. If you don't, you seem to be comparing a solution
to a non-solution.


Best

Kai-Uwe Bux
  Réponse avec citation
Vieux 02/07/2008, 15h39   #10
J. Cochran
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Is there an algorithm for integer multiply and divide at the same time?

In article <486b7678$0$12846$c3e8da3@news.astraweb.com>,
Default User <nospam38925@forme.com> wrote:
>Hi,
>
>> There's the MulDiv function from Windows, which is implemented in ReactOS
>> http://www.reactos.org/generated/dox...8c-source.html

>
>
>Thanks for the ideas guys, this is basically what I am looking for, but this
>code counts on RtlEnlargedUnsignedDivide which in turn counts on
>(ULONGLONG).
>
>I realize there are bignum libraries out there, but I am really only looking
>for a small single algorithm to do this. I will be dealing with integers
>only, and in such a way that I balance the Numerator/Denominator so that I
>know the result will fit properly.
>
>In this case I am looking to make 64 bit integers perform 128 bit like
>multiplication/division, but I would think I could easily adapt code
>designed to make 32 bit integers perform 64 bit like
>multiplication/division. Does anyone have any simple/short code made 64 bit
>integers from 32 bit integers, from a time before 64 bit integers were
>available natively in the compiler?
>
>The calculations I am trying to perform can be done in double, but it is 150
>times slower according to some testing I've done which is why I'd rather
>stick to integers if I can.
>
>Thanks,
>
>Alan


Take a look at
The Art of Computer Programming
Seminumerical Algorithms
Vol 2.
by Donald Knuth

You don't need to go to a full up big num package since what you're really
wanting is just double precision. So it should be possible for you to
write some small double precision functions that will provide you what you're
looking for.

For instance, you can do a double precision integer multiplication by
doing 3 single precision multiplies along with a few shifts and adds.

Good luck on your search. I'd suggest looking for some double precision
integer packages.
  Réponse avec citation
Vieux 02/07/2008, 16h45   #11
Jerry Coffin
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Is there an algorithm for integer multiply and divide at the same time?

In article <2c978e11-405e-4add-977f-
7e937e68d24c@l64g2000hse.googlegroups.com>, james.kanze@gmail.com
says...

[ ... ]

> Do you know of such a platform? The intermediate value he's
> concerned with can have up to 127 bits, so you'd need a mantissa
> of 127 bits. I think some have existed (perhaps some of the old
> CDC mainframes), but I don't know of any today.


Nope -- on the old CDC mainframes, single precision as 60 bits and
double precision was 100 bits -- but that's still for the whole thing,
including a 20-bit exponent, so the largest significand was 80 bits.

I believe some compilers for the Crays and DEC Alphas did marginally
better, with a 128-bit floating point number, but again that was for the
significand AND exponent, not the exponent alone.

--
Later,
Jerry.

The universe is a figment of its own imagination.
  Réponse avec citation
Vieux 02/07/2008, 16h50   #12
terminator
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Is there an algorithm for integer multiply and divide at the sametime?

On Jul 2, 7:16am, Kai-Uwe Bux <jkherci...@gmx.net> wrote:
> Default User wrote:
> > Hi,

>
> >> There's the MulDiv function from Windows, which is implemented in ReactOS
> >>http://www.reactos.org/generated/dox...8c-source.html

>
> > Thanks for the ideas guys, this is basically what I am looking for, but
> > this code counts on RtlEnlargedUnsignedDivide which in turn counts on
> > (ULONGLONG).

>
> > I realize there are bignum libraries out there, but I am really only
> > looking
> > for a small single algorithm to do this. I will be dealing with integers
> > only, and in such a way that I balance the Numerator/Denominator so thatI
> > know the result will fit properly.

>
> > In this case I am looking to make 64 bit integers perform 128 bit like
> > multiplication/division, but I would think I could easily adapt code
> > designed to make 32 bit integers perform 64 bit like
> > multiplication/division. Does anyone have any simple/short code made 64
> > bit integers from 32 bit integers, from a time before 64 bit integers were
> > available natively in the compiler?

>
> Addition is easy.
>
> Multiplication can be done like so: split the 64bit factors into high and
> low unsinged longs of 32 bits. Then you have to compute
>
> ( a * 2^32 + b ) * ( c * 2^32 + d )
> =
> a*c *2^64
> +
> (a-b)*(d-c) *2^32
> +
> a*c *2^32
> +
> b*d *2^32
> +
> c*d;
>
> which requires computing the three 64bit products ac, (a-b)(d-c), and cd.
> The rest is bit shifting and addition (which we agreed is easy :-).
>
> Alternatively, you could also do:
>
> ( a * 2^32 + b ) * ( c * 2^32 + d )
> =
> a*c *2^64
> +
> a*d *2^32
> +
> b*c *2^32
> +
> b*d
>
> which requires computing four 64bit products but is slightly less demanding
> on additions and bit shifting (also it does not involve dealing with
> differences).
>
> The tricky part is division. I have no idea how to do that efficiently.
>
> > The calculations I am trying to perform can be done in double, but it is
> > 150 times slower according to some testing I've done which is why I'd
> > rather stick to integers if I can.

>
> 150 times slower compared to what? If you already have a solution that beats
> floating point arithmetic by a factor of 150, you are probably all set and
> it won't get any better. If you don't, you seem to be comparing a solution
> to a non-solution.
>
> Best
>
> Kai-Uwe Bux


not sure but if one splits the 128-bit product in to 64-bit digits:

int64 proH,proL;

then (s)he might be able to use the algorithm that has been used - for
hundreds of years - to manually calculate the decimal division of
numbers.I am a computer generation guy and do not remember how I used
to divide two numbers in primary school mathematics course but
somebody must remember it.

regards,
FM.
  Réponse avec citation
Vieux 02/07/2008, 18h31   #13
Diego Martins
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Is there an algorithm for integer multiply and divide at the sametime?

On Jul 2, 12:50pm, terminator <farid.mehr...@gmail.com> wrote:
> I am a computer generation guy and do not remember how I used
> to divide two numbers in primary school mathematics course but
> somebody must remember it.


how sad
  Réponse avec citation
Vieux 02/07/2008, 18h43   #14
Kai-Uwe Bux
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Is there an algorithm for integer multiply and divide at the same time?

terminator wrote:

> On Jul 2, 7:16am, Kai-Uwe Bux <jkherci...@gmx.net> wrote:
>> Default User wrote:

[snip]
>> > In this case I am looking to make 64 bit integers perform 128 bit like
>> > multiplication/division, but I would think I could easily adapt code
>> > designed to make 32 bit integers perform 64 bit like
>> > multiplication/division. Does anyone have any simple/short code made
>> > 64 bit integers from 32 bit integers, from a time before 64 bit
>> > integers were available natively in the compiler?

[snip]
>> The tricky part is division. I have no idea how to do that efficiently.

[snip]
>
> not sure but if one splits the 128-bit product in to 64-bit digits:
>
> int64 proH,proL;
>
> then (s)he might be able to use the algorithm that has been used - for
> hundreds of years - to manually calculate the decimal division of
> numbers.I am a computer generation guy and do not remember how I used
> to divide two numbers in primary school mathematics course but
> somebody must remember it.


Well, the paper and pencil method of long division requires that you _know_
the multiplication table for one-digit numbers, i.e., you can divide
two-digit numbers by one-digit numbers provided the result has only one
digit. So using base 2^64 for the computation will not quite work. You
could use base 2^32 and use four digits.

However, even then the pencil and paper method you were taught requires a
certain degree of guesswork which has to be replaces by rigorous analysis.
Knuth has an exposition of that.


Best

Kai-Uwe Bux
  Réponse avec citation
Vieux 03/07/2008, 05h44   #15
Jerry Coffin
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Is there an algorithm for integer multiply and divide at the same time?

In article <g4geok$fv1$1@aioe.org>, jkherciueh@gmx.net says...

[ ... ]

> However, even then the pencil and paper method you were taught requires a
> certain degree of guesswork which has to be replaces by rigorous analysis.
> Knuth has an exposition of that.


There's no guesswork needed when you're working in binary. When you're
working in decimal, you need to figure out one digit of the answer --
i.e. figure out the largest multiple of the divisor (shifted left N
digits) that's smaller than the dividend. Since you're working in
decimal, that number can be anywhere from 0 to 9.

When you're working in binary, that number can only be from 0 to 1, so
you don't have to guess at anything -- either the shifted divisor is
smaller than the current dividend, or it's not. If it's smaller, the
current digit in the answer is a 1. If it's not, the current digit in
the answer is a zero.

Here's a small class that does bitwise multiplication and division on
integers (unsigned, in this case):

class integer {

unsigned value;

public:
integer(unsigned init) : value(init) { }

integer operator/(integer const &other) {
unsigned divisor = other.value;
int shift_count = 0;
unsigned answer = 0;
unsigned dividend = value;

if (divisor == 0)
return 0;

while (divisor < dividend) {
divisor <<= 1;
++shift_count;
}

for (;shift_count>-1; --shift_count, divisor>>=1) {
if (divisor <= dividend) {
answer |= (1 << shift_count);
dividend -= divisor;
}
}
return answer;
}

integer operator*(integer const &other) {
unsigned temp1 = other.value;
unsigned temp2 = value;
unsigned answer = 0;

while (temp1 != 0) {
if (temp1 & 1)
answer += temp2;
temp2 <<= 1;
temp1 >>=1;
}
return integer(answer);
}

integer operator+(integer const &other) {
return integer(value+other.value);
}

integer operator-(integer const &other) {
return integer(value-other.value);
}

operator<(integer const &other) const {
return value < other.value;
}

friend std:stream &operator<<(std:stream &os, integer const &i)
{
return os << i.value;
}

friend std::istream &operator>>(std::istream &is, integer &i) {
return is >> i.value;
}
};

Of course, there are other multiplication and division algorithms around
-- in fact, I don't believe this division algorithm is what's used in
most modern hardware.

--
Later,
Jerry.

The universe is a figment of its own imagination.
  Réponse avec citation
Vieux 03/07/2008, 06h06   #16
Kai-Uwe Bux
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Is there an algorithm for integer multiply and divide at the same time?

Jerry Coffin wrote:

> In article <g4geok$fv1$1@aioe.org>, jkherciueh@gmx.net says...
>
> [ ... ]
>
>> However, even then the pencil and paper method you were taught requires a
>> certain degree of guesswork which has to be replaces by rigorous
>> analysis. Knuth has an exposition of that.

>
> There's no guesswork needed when you're working in binary. When you're
> working in decimal, you need to figure out one digit of the answer --
> i.e. figure out the largest multiple of the divisor (shifted left N
> digits) that's smaller than the dividend. Since you're working in
> decimal, that number can be anywhere from 0 to 9.
>
> When you're working in binary, that number can only be from 0 to 1, so
> you don't have to guess at anything -- either the shifted divisor is
> smaller than the current dividend, or it's not. If it's smaller, the
> current digit in the answer is a 1. If it's not, the current digit in
> the answer is a zero.

[code snipped]

The point is that the OP wants to work in base 2^64 not in base 2. Of
course, it is easy to translate; however, the resulting algorithm is not
all that efficient since it has to extract the binary digits of the
quotient one by one. On the plus side: all other operations are just
shifts, subtractions, and comparisons, which are all fairly cheap.

Elsethread the OP already remarked that he could use double but was afraid
that the performance penalty might be too high. I would not expect the
paper and pencil method in binary to beat hardware division. However, only
measurement will show.


Best

Kai-Uwe Bux
  Réponse avec citation
Vieux 03/07/2008, 08h49   #17
Michael DOUBEZ
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Is there an algorithm for integer multiply and divide at thesame time?

Diego Martins a écrit :
> On Jul 2, 12:50 pm, terminator <farid.mehr...@gmail.com> wrote:
>> I am a computer generation guy and do not remember how I used
>> to divide two numbers in primary school mathematics course but
>> somebody must remember it.

>
> how sad


It must be an euclidian division. Look it up on Wikipedia or a math
related site.

The quickest way to solve the OP problem would be to use a
multiprecision library (at least locally); GMP comes to mind but there
are others that could be lighter.

--
Michael
  Réponse avec citation
Vieux 03/07/2008, 09h15   #18
James Kanze
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Is there an algorithm for integer multiply and divide at the sametime?

On Jul 3, 7:06 am, Kai-Uwe Bux <jkherci...@gmx.net> wrote:
> Jerry Coffin wrote:
> > In article <g4geok$fv...@aioe.org>, jkherci...@gmx.net says...


> > [ ... ]

> Elsethread the OP already remarked that he could use double
> but was afraid that the performance penalty might be too high.


Which makes me wonder. On my machine, a multiply followed by a
divide is faster in double than in int.

If speed is really an issue, and the hardware is an x86-64, then
his problem can be solved with two machine instructions:
multiplying two 64 bit values results in a 128 bit value, and
division is a 128 bit value divided by a 64 bit value.
Historically, having a multiply instruction which returned a
value with twice the width of its operands, and having division
which took a numerator of twice the width of the denominator and
the result were pretty much standard practice at the assembler
level. Modern architectures seem to have gotten away from this,
however, because no high level language supports it, and the
extra registers it uses introduced awkward constraints in the
register allocation routines in the compiler. (On the IBM 360's
architecture, the C compiler I used always used R0/R1 for
multiplication and division, and never used these registers for
anything else. Which, of course, doesn't result in particularly
good optimization.)

> I would not expect the paper and pencil method in binary to
> beat hardware division. However, only measurement will show.


I would normally expect that if you wrote a*b/c, a good compiler
on an Intel architecture would generate something which would
actually give the right results, even if there was an
intervening overflow (at least for signed values---the standard
doesn't allow it for unsigned), not for any intrinsic reasons,
but because the fastest code to evaluate this expression will
give the right results (and according to the standard, if
overflow occurs, the behavior is undefined, so it's certainly
not incorrect to give the correct results). A quick look at the
code generated by g++, however (for 32 bits, since the only
Intel architectures I have access to here are 32 bits), shows
that it systematically inserts an extra cltd instruction between
the multiply and the divide. (CLTD seems to correspond to what
Intel names CDQ.) Whether this is intentional, because g++
defines behavior in case of overflow, or whether it is simply
careless code generation (if the operand to the multiply comes
from any source other than the results of a division, it is
necessary), I don't know.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
  Réponse avec citation
Réponse


Outils de la discussion

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Trackbacks are oui
Pingbacks are oui
Refbacks are oui


Fuseau horaire GMT +1. Il est actuellement 19h15.


Édité par : vBulletin® version 3.7.3
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0 RC5 Tous droits réservés.
Version française #16 par l'association vBulletin francophone
PHWinfo est un site Éducation Sans Frontières ©2000-2008
Ad Management by RedTyger
©Tous droits réservés par les parties respectives
Page generated in 0,71268 seconds with 26 queries