# Divide by zero.

Discussion in 'C++' started by shuisheng, Sep 25, 2006.

1. ### shuishengGuest

Dear all,

Assume I have two big arrays A and B. And I want to element-wise divide
A by B. When an element of B is zero, the results are also zero.

Such as A = { 2, 4, 0, 6}
B = { 1, 0, 0, 2}
-----------------------------------------
R = { 2, 0, 0, 3}

Any fast way to avoid the slow 'if' operation.

Thanks,

Shuisheng

shuisheng, Sep 25, 2006

2. ### Victor BazarovGuest

shuisheng wrote:
> Assume I have two big arrays A and B. And I want to element-wise
> divide A by B. When an element of B is zero, the results are also
> zero.
>
> Such as A = { 2, 4, 0, 6}
> B = { 1, 0, 0, 2}
> -----------------------------------------
> R = { 2, 0, 0, 3}
>
> Any fast way to avoid the slow 'if' operation.

You like to avoid things, don't you?

How slow is it? If you take two arrays such that B doesn't have
any zeros in it, how much does 'if' slow you down? Is it really
so significant? AFAIUI, you cannot avoid some kind of checking
against 0 to prevent division by 0, right? You could try playing
tricks with arithmetic, but it is most likely just as expensive
as comparing B with 0.

V
--

Victor Bazarov, Sep 25, 2006

3. ### Frederick GothamGuest

shuisheng posted:

> Dear all,
>
> Assume I have two big arrays A and B. And I want to element-wise divide
> A by B. When an element of B is zero, the results are also zero.
>
> Such as A = { 2, 4, 0, 6}
> B = { 1, 0, 0, 2}
> -----------------------------------------
> R = { 2, 0, 0, 3}
>
> Any fast way to avoid the slow 'if' operation.

The fastest code I can think of at the moment is the following (but
ofcourse, it tests a conditional):

#include <cstddef>
#include <cassert>

void Divide(int *pA, int const *pB, std::size_t const len)
{
assert(pA); assert(pB); assert(len);

int register temp;

int const *const poverA = pA + len;

do (temp = *pB++) ? (*pA++ /= temp) : (*pA++ = 0);
while(poverA!=pA);
}

Or maybe if you're working with a machine which has a single instruction
which takes a pointer plus an offset:

void Divide(int *const pA, int const *const pB, std::size_t const len)
{
assert(pA); assert(pB); assert(len);

int register temp;

std::size_t register i = 0;

do (temp = pB) ? (pA /= temp) : (pA = 0);
while(++i!= len);
}

--

Frederick Gotham

Frederick Gotham, Sep 25, 2006
4. ### shuishengGuest

Victor Bazarov å†™é“ï¼š

> How slow is it? If you take two arrays such that B doesn't have
> any zeros in it, how much does 'if' slow you down? Is it really
> so significant? AFAIUI, you cannot avoid some kind of checking
> against 0 to prevent division by 0, right? You could try playing
> tricks with arithmetic, but it is most likely just as expensive
> as comparing B with 0.

The difference is very small: sevral percents and some times even the
same. Thanks!!!

Shuisheng

shuisheng, Sep 25, 2006
5. ### Victor BazarovGuest

shuisheng wrote:
> Victor Bazarov ??:
>
>> How slow is it? If you take two arrays such that B doesn't have
>> any zeros in it, how much does 'if' slow you down? Is it really
>> so significant? AFAIUI, you cannot avoid some kind of checking
>> against 0 to prevent division by 0, right? You could try playing
>> tricks with arithmetic, but it is most likely just as expensive
>> as comparing B with 0.

>
> The difference is very small: sevral percents and some times even the
> same. Thanks!!!

Hey, don't mention it!

OK, how much of your application does division of the two arrays take?
If it's about 10 percent total (from start to finish), then if you
shave off another 10 percent of that by removing (magically) the 'if',
what is the final improvement for the application? 1 percent at best?
Is it worth the time you spend trying to find the magic to remove the
pesky 'if'?

V
--