473,503 Members | 4,272 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

find out the problem

Hi to all. find out the biggest among two numbers without using any
conditional statements and any relational operators.

Nov 15 '05 #1
50 4128


sabarish wrote:
Hi to all. find out the biggest among two numbers without using any
conditional statements and any relational operators.


This cannot be done, not even by using non-portable
trickery. The reason is simple: there is no such thing
as the "biggest" of just two numbers. The superlative
form of an adjective implies three or more alternatives.

Had you written "bigger" the answer might have been
different -- but that would have made the question sound
like homework, and we can't have that, can we?

--
Er*********@sun.com

Nov 15 '05 #2
Eric Sosman <er*********@sun.com> wrote:
sabarish wrote:
Hi to all. find out the biggest among two numbers without using any
conditional statements and any relational operators.


This cannot be done, not even by using non-portable
trickery. The reason is simple: there is no such thing
as the "biggest" of just two numbers. The superlative
form of an adjective implies three or more alternatives.


No, they don't. Check the OED. What you describe is merely customary in
some circles, but not the only correct usage.

Richard
Nov 15 '05 #3
sabarish wrote:

Hi to all. find out the biggest among two numbers without using any
conditional statements and any relational operators.


So, how many open NNTP proxies do you have access to?

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>

Nov 15 '05 #4
result=(x-y) //subtract y from x
//if x>y result is +ve else -ve

result=result >>31 //get the sign bit to last bit
result=result&0x01 //mask the last bit

return x*result + y*(~result & 0x1)

if result =1 x will be returned as ~result&0x1 would be 0

Nov 15 '05 #5
In article <11**********************@g47g2000cwa.googlegroups .com>,
<ag*************@gmail.com> wrote:
result=(x-y) //subtract y from x
//if x>y result is +ve else -ve


Why would the result be negative if the two values are equal?
--
This signature intentionally left... Oh, darn!
Nov 15 '05 #6


Richard Bos wrote:
Eric Sosman <er*********@sun.com> wrote:

sabarish wrote:
Hi to all. find out the biggest among two numbers without using any
conditional statements and any relational operators.
This cannot be done, not even by using non-portable
trickery. The reason is simple: there is no such thing
as the "biggest" of just two numbers. The superlative
form of an adjective implies three or more alternatives.

No, they don't. Check the OED.


No thanks; I've got other uses for $295.
What you describe is merely customary in
some circles, but not the only correct usage.


"Some circles" meaning "Those who value English," I
guess ...

Does the OED list "irregardless?" Does it list "verb"
as a transitive verb? Does it endorse the sportscasters'
monstrous misuse of the present indicative for the subjunctive
("If I'm Alex Rodriguez I'm looking fast ball here")? We're
down to the old prescriptive vs. descriptive debate, and I for
one choose not use a description of other people's bad usage
as a prescription for my own. Harrumph!

--
Er*********@sun.com
Nov 15 '05 #7
"sabarish" <su******@gmail.com> writes:
Hi to all. find out the biggest among two numbers without using any
conditional statements and any relational operators.


This question has been beaten to death over the years. Try
searching the archives.
--
"To get the best out of this book, I strongly recommend that you read it."
--Richard Heathfield
Nov 15 '05 #8
sabarish wrote:
Hi to all. find out the biggest among two numbers without using any
conditional statements and any relational operators.


It's simple as well as off topic (since it's not C specific):

max(x, y) = (x + y + |x - y|) / 2
August
Nov 15 '05 #9
ag*************@gmail.com writes:
result=(x-y) //subtract y from x
//if x>y result is +ve else -ve

result=result >>31 //get the sign bit to last bit
result=result&0x01 //mask the last bit

return x*result + y*(~result & 0x1)

if result =1 x will be returned as ~result&0x1 would be 0


That has so many portability problems I'm not going to bother to
decide whether it's correct.

--
Keith Thompson (The_Other_Keith) 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.
Nov 15 '05 #10


akarl wrote:
sabarish wrote:
Hi to all. find out the biggest among two numbers without using any
conditional statements and any relational operators.

It's simple as well as off topic (since it's not C specific):

max(x, y) = (x + y + |x - y|) / 2


Try it with x = LDBL_MAX and y = -LDBL_MAX, and tell us
again just how "simple" it is.

Do other such misbehaving pairs exist? Oh yes, oh yes,
they most definitely do. I ran a simple test on a million
pairs of randomly-generated[*] `double' values, on which
akarl's formula delivered the right answer 596230 times --
and gave a wrong answer the other 403770 times. If you can
tolerate error rates of 40% or so, by all means use akarl's
"simple" formula.
[*] Not from a uniform distribution. I wanted a wide
spread of magnitudes, so I used tan(rand() * PI / RAND_MAX).

--
Er*********@sun.com

Nov 15 '05 #11
"sabarish" <su******@gmail.com> writes:
Hi to all. find out the biggest among two numbers without using any
conditional statements and any relational operators.


Use relational operators. That's what they're for.

If there's some reason you need to do this without using the features
of the language designed for that purpose, you should explain why if
you expect any help.

If the reason is that it's a homework assignment (which is the only
explanation I can think of), do it yourself.

--
Keith Thompson (The_Other_Keith) 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.
Nov 15 '05 #12
Eric Sosman wrote:

akarl wrote:
sabarish wrote:

Hi to all. find out the biggest among two numbers without using any
conditional statements and any relational operators.

It's simple as well as off topic (since it's not C specific):

max(x, y) = (x + y + |x - y|) / 2

Try it with x = LDBL_MAX and y = -LDBL_MAX, and tell us
again just how "simple" it is.

Do other such misbehaving pairs exist? Oh yes, oh yes,
they most definitely do. I ran a simple test on a million
pairs of randomly-generated[*] `double' values, on which
akarl's formula delivered the right answer 596230 times --
and gave a wrong answer the other 403770 times. If you can
tolerate error rates of 40% or so, by all means use akarl's
"simple" formula.

[*] Not from a uniform distribution. I wanted a wide
spread of magnitudes, so I used tan(rand() * PI / RAND_MAX).


Note that I've only presented a mathematical formula, not a C
implementation ;-) However the whole matter is more of theoretical
interest; Why would anyone want to implement it without relational
operators?
August

Nov 15 '05 #13
"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
ag*************@gmail.com writes:
result=(x-y) //subtract y from x
//if x>y result is +ve else -ve

result=result >>31 //get the sign bit to last bit
result=result&0x01 //mask the last bit

return x*result + y*(~result & 0x1)

if result =1 x will be returned as ~result&0x1 would be 0


That has so many portability problems I'm not going to bother to
decide whether it's correct.


The correct would be (on a 2's complemented target where the right shift
operator performed on a signed value keeps the MSBit/sign bit, aka Shift
Right Arithmetic):

#include <stdio.h>

/* BITS_IN_LONG says how many bits are in long, can be computed (at run time
but then it'll be a variable not macro) or if exists such a define somewhere
in the std libc headers, can be taken right from there: */
#define BITS_IN_LONG 32

long Max(long x, long y)
{
long res;
res = (x-y) >> BITS_IN_LONG; /* res=0 (all zeroes) or -1 (all ones) */
res = (x & ~res) | (y & res); /* depending on prev value of res, we just
select/multiplex x or y by means of bitwise masking */
return res;
}

int main()
{
printf ("%ld\n", Max(-1,-1));
printf ("%ld\n", Max(-1, 0));
printf ("%ld\n", Max(-1, 1));
printf ("%ld\n", Max( 0,-1));
printf ("%ld\n", Max( 0, 0));
printf ("%ld\n", Max( 0, 1));
printf ("%ld\n", Max( 1,-1));
printf ("%ld\n", Max( 1, 0));
printf ("%ld\n", Max( 1, 1));
return 0;
}
Gives as expected:
-1
0
1
0
0
1
1
1
1

I'd suggest the newbies learn boolean stuff and digital logic better (or at
all if never studied before). I know that the above thing has a limited use,
but the limit is many millions of CPUs where it would work just fine.
And honestly, fixed point math (where people often use similar tricks) is
much more portable than floating point. It will yield the same result (if
coded properly, of course) on all targets and compilers, whereas floating
point will almost always give different LSBit (due to optimization,
operation reordering or because of simply being not IE754 compliant or using
shorter floating types) and since the errors tend to accumulate, the
difference can be bigger.

There're a few great docs on the subjects:
Sun's Numerical Computation Guide / What Every Computer Scientist Should
Know About Floating-Point Arithmetic by Goldberg
and
Algorithms For Programmers ideas and source code by Arndt

HTH
Alex
Nov 15 '05 #14
On 1 Aug 2005 09:01:02 -0700, ag*************@gmail.com wrote in
comp.lang.c:

Your decision to use the broken Google interface DOES NOT entitle you
to inflict the bad manners of responses with NO CONTEXT. LEARN HOW TO
QUOTE PROPERLY.

Hmmm...

double return_larger(double x, double y)
{
double result;
/* so far so good */
result=(x-y) //subtract y from x
//if x>y result is +ve else -ve
Complaint about missing ;
result=result >>31 //get the sign bit to last bit
result=result&0x01 //mask the last bit

return x*result + y*(~result & 0x1)

if result =1 x will be returned as ~result&0x1 would be 0


....just a few messages from an unhappy compiler.
Now as the OP's original question was:
Hi to all. find out the biggest among two numbers without using any
conditional statements and any relational operators.


....where did he say integer types?

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 15 '05 #15

Alexei A. Frounze wrote:
"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
ag*************@gmail.com writes:

[snip]
The correct would be (on a 2's complemented target where the right shift
operator performed on a signed value keeps the MSBit/sign bit, aka Shift
Right Arithmetic):

#include <stdio.h>

/* BITS_IN_LONG says how many bits are in long, can be computed (at run time
but then it'll be a variable not macro) or if exists such a define somewhere
in the std libc headers, can be taken right from there: */
#define BITS_IN_LONG 32

long Max(long x, long y)
{
long res;
res = (x-y) >> BITS_IN_LONG; /* res=0 (all zeroes) or -1 (all ones) */
It invokes UB. C99 6.5.7p3

"If the value of the right operand is negative or is greater than or
equal to the width of the promoted left operand, the behavior is
undefined."

res = (x & ~res) | (y & res); /* depending on prev value of res, we just
select/multiplex x or y by means of bitwise masking */
return res;
}


Krishanu

--
"What we need is less people running around and telling everyone else
what to do and more people actually writing code."
--Linus Torvalds

Nov 15 '05 #16
"Krishanu Debnath" <kr**************@gmail.com> wrote in message
news:11*********************@z14g2000cwz.googlegro ups.com...
....
long Max(long x, long y)
{
long res;
res = (x-y) >> BITS_IN_LONG; /* res=0 (all zeroes) or -1 (all ones) */


It invokes UB. C99 6.5.7p3

"If the value of the right operand is negative or is greater than or
equal to the width of the promoted left operand, the behavior is
undefined."


I know it's undefined *by standard*. But it's pretty much well defined by so
many compilers out there... Can one name a compiler that issues an error at
that shift operator or yields garbage or freaks out? Can anyone name one
that doesn't extend/propagate the sign bit to the right? I'm asking out of
curiousity, since 6 or 7 compilers that I know would handle that just right
(on about 5 entirely different CPUs, ix86 and several non-ix86).

Alex
Nov 15 '05 #17
>> > long res;
> res = (x-y) >> BITS_IN_LONG; /* res=0 (all zeroes) or -1 (all ones) */
It invokes UB. C99 6.5.7p3

"If the value of the right operand is negative or is greater than or
equal to the width of the promoted left operand, the behavior is
undefined."


I know it's undefined *by standard*. But it's pretty much well defined by so
many compilers out there... Can one name a compiler that issues an error at
that shift operator or yields garbage or freaks out? Can anyone name one


There are a number of assembly languages where the shift count can
be a variable but only a small number of bits are used. Higher-order
bits in the count are ignored. (Typically a shift of the number
of bits in the word is equivalent to a shift of 0 (no change) rather
than filling the entire word with the sign bit or with zeroes.)

Compilers typically take the shift count, stuff it in a register,
and use the register for the shift count in a shift instruction.
If the shift count is out of range for the instruction, let the
nasal demons fly where they may.

For a specific example: Intel Pentium, gcc 3.4.2 on FreeBSD. A
shift of N bits of an int or long (32 bits in this case) to the
right seems to be treated the same as a shift of (N%32) bits to the
right *WHEN THE SHIFT COUNT IS VARIABLE*. This is "wrong" according
to what people would expect a shift to do. You get different results
sometimes if the shift amount is a constant rather than a variable.
that doesn't extend/propagate the sign bit to the right? I'm asking out of
curiousity, since 6 or 7 compilers that I know would handle that just right
(on about 5 entirely different CPUs, ix86 and several non-ix86).


The code:

#include <stdio.h>
int x(int a)
{
printf("%d: %lx\n", a, 0x12345678 >> a);
return 0;
}
int main(void)
{
x(36);
x(32);
x(0);
return 0;
}

The output (annotated to the right):
36: 1234567 Same as a shift of 4
32: 12345678 Same as no shift at all
0: 12345678

Gordon L. Burditt
Nov 15 '05 #18
Gordon Burditt sade:
For a specific example: Intel Pentium, gcc 3.4.2 on FreeBSD. A
[snippy-snip]
int main(void)
{
x(36);
x(32);
On all IA-32 processors starting with Intel 286, the shift count
is masked to 5 bits, resulting in a maximum count of 31.

(IA-32 Intel Architecture Software Developer's Manual Volume 2, page 737)

Hence:
The output (annotated to the right):
36: 1234567 Same as a shift of 4
32: 12345678 Same as no shift at all
0: 12345678


Tobias
--
IMPORTANT: The contents of this email and attachments are confidential
and may be subject to legal privilege and/or protected by copyright.
Copying or communicating any part of it to others is prohibited and may
be unlawful.
Nov 15 '05 #19
"Gordon Burditt" <go****@hammy.burditt.org> wrote in message
news:11*************@corp.supernews.com...
....
There are a number of assembly languages where the shift count can
be a variable but only a small number of bits are used. Higher-order
bits in the count are ignored. (Typically a shift of the number
of bits in the word is equivalent to a shift of 0 (no change) rather
than filling the entire word with the sign bit or with zeroes.)
Yep.
Compilers typically take the shift count, stuff it in a register,
and use the register for the shift count in a shift instruction.
If the shift count is out of range for the instruction, let the
nasal demons fly where they may.
I've seen that and was very surprised.
For a specific example: Intel Pentium, gcc 3.4.2 on FreeBSD. A
shift of N bits of an int or long (32 bits in this case) to the
right seems to be treated the same as a shift of (N%32) bits to the
right *WHEN THE SHIFT COUNT IS VARIABLE*. This is "wrong" according
to what people would expect a shift to do. You get different results
sometimes if the shift amount is a constant rather than a variable.

The code:

#include <stdio.h>
int x(int a)
{
printf("%d: %lx\n", a, 0x12345678 >> a);
return 0;
}
int main(void)
{
x(36);
x(32);
x(0);
return 0;
}

The output (annotated to the right):
36: 1234567 Same as a shift of 4
32: 12345678 Same as no shift at all
0: 12345678


That all is correct, no doubt, however, my personal opinion is that that's
wrong to take the shift count and blindly feed it to the asm instruction
with such a limitation. It's as illogical as the need to cast one of two
integer multipliers to long integer in order to get the correct long integer
product. That strikes the math guys in the back. Anyway, I was talking about
a slightly different problem of the shift -- whether or not it's SAR-like or
something else, especially something very odd, probably not any kind of
shift at all.

Alex
Nov 15 '05 #20
>> The code:

#include <stdio.h>
int x(int a)
{
printf("%d: %lx\n", a, 0x12345678 >> a);
return 0;
}
int main(void)
{
x(36);
x(32);
x(0);
return 0;
}

The output (annotated to the right):
36: 1234567 Same as a shift of 4
32: 12345678 Same as no shift at all
0: 12345678
That all is correct, no doubt, however, my personal opinion is that that's
wrong to take the shift count and blindly feed it to the asm instruction
with such a limitation.


ANSI C says it's ok. It probably does that because lots of compilers,
I suspect from the PDP-11 on, did just that. Personally, I agree
with you; out-of-range counts should cause core dumps. But the
speed freaks don't like it.
It's as illogical as the need to cast one of two
integer multipliers to long integer in order to get the correct long integer
product.
I don't agree that the cast is illogical. And dealing with this
doesn't have to generate inefficient code in the cases where it's
NOT needed, unlike the shift case, which slows down all variable shifts.
That strikes the math guys in the back. Anyway, I was talking about
a slightly different problem of the shift -- whether or not it's SAR-like or
something else, especially something very odd, probably not any kind of
shift at all.


I have heard of some peculiar cases where shift used rotate instead
(there were no shift instructions on that machine) and some masking
was used which went a bit haywire when the count was out of range.
I don't remember what machine it was, though.

Gordon L. Burditt

Nov 15 '05 #21
Groovy hepcat sabarish was jivin' on 1 Aug 2005 07:24:07 -0700 in
comp.lang.c.
find out the problem's a cool scene! Dig it!
Hi to all. find out the biggest among two numbers without using any
conditional statements and any relational operators.


No.

But don't let me stop you from doing so, if you wish. If you have
any problems with it, ask specific questions, including your code (or
the smallest *complete* program that shows the problems) in the post,
and we'll endeavour to answer your queries and help you fix the code.

--

Dig the even newer still, yet more improved, sig!

http://alphalink.com.au/~phaywood/
"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
Nov 15 '05 #22

Alexei A. Frounze wrote:
"Krishanu Debnath" <kr**************@gmail.com> wrote in message
news:11*********************@z14g2000cwz.googlegro ups.com...
...
long Max(long x, long y)
{
long res;
res = (x-y) >> BITS_IN_LONG; /* res=0 (all zeroes) or -1 (all ones) */
It invokes UB. C99 6.5.7p3

"If the value of the right operand is negative or is greater than or
equal to the width of the promoted left operand, the behavior is
undefined."


I know it's undefined *by standard*. But it's pretty much well defined by so
many compilers out there... Can one name a compiler that issues an error at


[x0030819 dcesparc017 SunOS c]: cat nonsense.c
#include<limits.h>
#include<stdio.h>

int main()
{
int number = -4;
number = number >> ( CHAR_BIT * sizeof number);
printf(" number %d \n", number);
return 0;
}
[x0030819 dcesparc017 SunOS c]:
[x0030819 dcesparc017 SunOS c]: gcc -dumpversion
3.4.2
[x0030819 dcesparc017 SunOS c]: gcc -ansi -pedantic -W -Wall nonsense.c
nonsense.c: In function `main':
nonsense.c:7: warning: right shift count >= width of type
[x0030819 dcesparc017 SunOS c]: ./a.out
number -4
[x0030819 dcesparc017 SunOS c]: uname -a
SunOS dcesparc017 5.8 Generic_108528-21 sun4u sparc SUNW,Ultra-5_10
[x0030819 dcesparc017 SunOS c]:
that shift operator or yields garbage or freaks out? Can anyone name one
that doesn't extend/propagate the sign bit to the right? I'm asking out of
curiousity, since 6 or 7 compilers that I know would handle that just right
(on about 5 entirely different CPUs, ix86 and several non-ix86).

Alex


Krishanu

Nov 15 '05 #23
In article <11**********************@g43g2000cwa.googlegroups .com>, sabarish wrote:
Hi to all. find out the biggest among two numbers without using any
conditional statements and any relational operators.


#include <math.h>
float a,b,biggest;
//...
biggest=a+b-fabs(a-b);
--

Bye.
Jasen
Nov 15 '05 #24
yes

This question is raised by mnc Companies......

and i solved this problem
main()
{
int a=10;
int b=20;

printf("%d",b+( ((a-b)+fabs(a-b))/2) );
}

thats it.

Nov 15 '05 #25
Thank u

you r absolutely correct sir
This is sabarish nice to meet to u and i have one more problem how can
i connect to the database through c Program(database is Oracle,
Operating system is windows 98).
can u help me, my id is ca***************@yahoo.co.in

Nov 15 '05 #26
Jasen Betts wrote:
In article <11**********************@g43g2000cwa.googlegroups .com>, sabarish wrote:
Hi to all. find out the biggest among two numbers without using any
conditional statements and any relational operators.

#include <math.h>
float a,b,biggest;
//...
biggest=a+b-fabs(a-b);


Yeah, right:

$ cat test.c
#include <math.h>
#include <stdio.h>

int main(void)
{
double a = 2, b = 3, max;

max = a + b - fabs(a - b);
printf("The maximum value of %f and %f is %f.\n", a, b, max);
return 0;
}

$ gcc test.c -o test

$ ./test
The maximum value of 2.000000 and 3.000000 is 4.000000.
August
Nov 15 '05 #27
sabarish wrote:
yes

This question is raised by mnc Companies......

and i solved this problem
main()
{
int a=10;
int b=20;

printf("%d",b+( ((a-b)+fabs(a-b))/2) );
}

thats it.


You obviously didn't read my first post in this thread.

August
Nov 15 '05 #28
In article <11**********************@g14g2000cwa.googlegroups .com>,
sabarish <su******@gmail.com> wrote:
This question is raised by mnc Companies......
I don't believe I recognize "mnc Companies" ?

and i solved this problem main()
{
int a=10;
int b=20;

printf("%d",b+( ((a-b)+fabs(a-b))/2) );
} thats it.


Improper declaration of main() for C89 or C99. Missing return value
of main for C89.

fabs() works on doubles, so fabs(a-b) will be a double and
that will be added to the int (a-b), producing a double. The
2 in the denominator will therefore be promoted to a double,
hence there will be a floating-point division, not an integer division.
The result will be a double, so the b of the addition will be promoted
to a double for the addition, with a double as a result of the expression.
It is not certain that the result of this expression will be
an exact representation of an integer, especially if one of the values
is close to the maximum or minimum integer -- you might get something
very -close- to an integer.

You then attempt to print that double as an integer without any
casting, and the result of that is going to depend upon the
implementation; in some implementations, it might print a random
value as floating point numbers are not always passed into routines the
same way that integral arguments are.

Your routine also breaks down if you get overflow in the a-b
portion, which could happen if b is a large negative number.

--
Entropy is the logarithm of probability -- Boltzmann
Nov 15 '05 #29
akarl wrote:
sabarish wrote:
Hi to all. find out the biggest among two numbers without using any
conditional statements and any relational operators.


It's simple as well as off topic (since it's not C specific):

max(x, y) = (x + y + |x - y|) / 2


Is it?
Implementation-wise, apart from the problematic cases, as Eric pointed
out, there is another issue. The absolute value. How do you compute it
with no conditional statement? Just using fabs() or some other
library function doesn't make it any better. There *has* to be some
conditional statement hidden somewhere. (Or else, tell me how you do
it.) So this doesn't solve the problem which says "without using any
conditional statements and any relational operators".

Ok, some implementations of fabs() may not need a conditional
statement (it may be able to modify the sign without any condition),
but that's not guaranteed.

And to me, formally speaking, an absolute value is a conditional
statement in itself.

Anyway, the question looked like YASHWA to me.
(= Yet Another Stupid HomeWork Assignment ;-) )
Nov 15 '05 #30
Guillaume wrote:
akarl wrote:
sabarish wrote:
Hi to all. find out the biggest among two numbers without using any
conditional statements and any relational operators.

It's simple as well as off topic (since it's not C specific):

max(x, y) = (x + y + |x - y|) / 2

Is it?
Implementation-wise, apart from the problematic cases, as Eric pointed
out, there is another issue. The absolute value. How do you compute it
with no conditional statement? Just using fabs() or some other
library function doesn't make it any better. There *has* to be some
conditional statement hidden somewhere. (Or else, tell me how you do
it.) So this doesn't solve the problem which says "without using any
conditional statements and any relational operators".

Ok, some implementations of fabs() may not need a conditional
statement (it may be able to modify the sign without any condition),
but that's not guaranteed.

And to me, formally speaking, an absolute value is a conditional
statement in itself.

Anyway, the question looked like YASHWA to me.
(= Yet Another Stupid HomeWork Assignment ;-) )


Yes, I see your point. On the other hand it seems like the formula I
presented was what sabarish was looking for.
Nov 15 '05 #31
On Wed, 03 Aug 2005 17:40:57 +0200, Guillaume
<> wrote:
akarl wrote:
sabarish wrote:
Hi to all. find out the biggest among two numbers without using any
conditional statements and any relational operators.
It's simple as well as off topic (since it's not C specific):

max(x, y) = (x + y + |x - y|) / 2


Is it?
Implementation-wise, apart from the problematic cases, as Eric pointed
out, there is another issue. The absolute value. How do you compute it
with no conditional statement? Just using fabs() or some other
library function doesn't make it any better. There *has* to be some
conditional statement hidden somewhere. (Or else, tell me how you do
it.) So this doesn't solve the problem which says "without using any
conditional statements and any relational operators".


abs(x) = sqrt(x*x)

Assuming 'perfect' arithmetic (no precision or limits problems) of
course (and assuming that sqrt(x) means "the positive square root of x",
but the latter is a given in standard C at least).
Anyway, the question looked like YASHWA to me.
(= Yet Another Stupid HomeWork Assignment ;-) )


Indeed. But by now the assignment has probably been done...

Chris C
Nov 15 '05 #32
"Krishanu Debnath" <kr**************@gmail.com> wrote in message
news:11**********************@g47g2000cwa.googlegr oups.com...
....
[x0030819 dcesparc017 SunOS c]: cat nonsense.c
#include<limits.h>
#include<stdio.h>

int main()
{
int number = -4;
number = number >> ( CHAR_BIT * sizeof number);


I did not mean the issue with the shift amount. What's the output if you
just shift by *1* position?

Alex
Nov 15 '05 #33
"Chris Croughton" <ch***@keristor.net> wrote in message
news:sl******************@ccserver.keris.net...
....
abs(x) = sqrt(x*x)


Anyway, computing the square root normally involves branches, at least to
make up the loop in which the value is computed, but I'm sure there're many
more inside, so, apparently, it's no good -- the branches are still
somewhere inside :)

Alex
Nov 15 '05 #34
In article <3l*************@individual.net>,
Alexei A. Frounze <al*****@chat.ru> wrote:
"Chris Croughton" <ch***@keristor.net> wrote in message
news:sl******************@ccserver.keris.net...
...
abs(x) = sqrt(x*x)
Anyway, computing the square root normally involves branches, at least to
make up the loop in which the value is computed, but I'm sure there're many
more inside, so, apparently, it's no good -- the branches are still
somewhere inside :)


Hardware square root instructions are pretty common; there are
different implementations, and I don't know whether -all- of them require
conditional branches (which implies a microcode execution, whereas
a big transistor mess would just -do- the computation.)

If one were using a hardware square root instruction, the terms
of the original posting would be satisfied -- the instruction -itself-
would not be conditional nor relational. It would be valid for
a standard math library implementation of sqrt() to use a hardware
square root instruction "behind the scenes".
Someone mentioned that absolute value requires conditional tests.
That's not the case for the IEEE standard representation of floating point
values, which has a sign bit that could be masked off with a
bitwise-and . This does get us back, though, to the small question
of what the data types are that the algorithm is required to handle.

Mind you, there is a two's-complement integer absolute value without
conditionals: e.g. something like

(signed long)((x) & LONG_MIN) +
(signed long)(((unsigned long)(x) & LONG_MIN) > (CHAR_BIT * sizeof long - 1))
Of course, just to detect whether you are 1's complement or 2's is
likely going to get you into conditionals...
--
Entropy is the logarithm of probability -- Boltzmann
Nov 15 '05 #35
ro******@ibd.nrc-cnrc.gc.ca (Walter Roberson) writes:
In article <11**********************@g14g2000cwa.googlegroups .com>,
sabarish <su******@gmail.com> wrote:
This question is raised by mnc Companies......
I don't believe I recognize "mnc Companies" ?

and i solved this problem

main()
{
int a=10;
int b=20;

printf("%d",b+( ((a-b)+fabs(a-b))/2) );
}

thats it.


Improper declaration of main() for C89 or C99. Missing return value
of main for C89.

fabs() works on doubles, so fabs(a-b) will be a double and
that will be added to the int (a-b), producing a double.


fabs() returns a double if you have a #include <math.h>. If you
don't, it invokes undefined behavior.

[snip]
You then attempt to print that double as an integer without any
casting, and the result of that is going to depend upon the
implementation; in some implementations, it might print a random
value as floating point numbers are not always passed into routines the
same way that integral arguments are.
Calling printf() without a valid prototype (preferably via #include
<stdio.h>) invokes undefined behavior. If that's corrected, passing a
double value to printf() with a "%d" format also invokes undefined
behavior. It might print a random value by tattooing it across your
forehead (unlikely, but allowed by the standard).
Your routine also breaks down if you get overflow in the a-b
portion, which could happen if b is a large negative number.


Yes.

--
Keith Thompson (The_Other_Keith) 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.
Nov 15 '05 #36
Alexei A. Frounze wrote:
...
long Max(long x, long y)
{
long res;
res = (x-y) >> BITS_IN_LONG; /* res=0 (all zeroes) or -1 (all ones) */


It invokes UB. C99 6.5.7p3

"If the value of the right operand is negative or is greater than or
equal to the width of the promoted left operand, the behavior is
undefined."


I know it's undefined *by standard*. But it's pretty much well defined by so
many compilers out there... Can one name a compiler that issues an error at
that shift operator or yields garbage or freaks out?


GCC 3, x86 (pretty uncommon, I know...)

Using your exact sample function, Max(-2, -2) gives 6,
and Max(2, 1) gives 3.

There is even a compiler warning:
gcc h.c -o h
h.c: In function `Max':
h.c:6: warning: right shift count >= width of type

Can you name one compiler that does operate your code correctly,
out of interest?

Nov 15 '05 #37
On Wed, 3 Aug 2005 23:17:22 +0400, Alexei A. Frounze
<al*****@chat.ru> wrote:
"Chris Croughton" <ch***@keristor.net> wrote in message
news:sl******************@ccserver.keris.net...
...
abs(x) = sqrt(x*x)


Anyway, computing the square root normally involves branches, at least to
make up the loop in which the value is computed, but I'm sure there're many
more inside, so, apparently, it's no good -- the branches are still
somewhere inside :)


Not necessarily, you can unroll the loop to any desired precision (as I
recall you get at least one bit improvement in accuracy for each
Newton-Raphson iteration, so repeating it 128 times should be sufficient
on most systems). But some floating point units do it in hardware...

Chris C
Nov 15 '05 #38
"Old Wolf" <ol*****@inspire.net.nz> wrote in message
news:11********************@g43g2000cwa.googlegrou ps.com...
Alexei A. Frounze wrote:
...
> long Max(long x, long y)
> {
> long res;
> res = (x-y) >> BITS_IN_LONG; /* res=0 (all zeroes) or -1 (all ones) */
It invokes UB. C99 6.5.7p3

"If the value of the right operand is negative or is greater than or
equal to the width of the promoted left operand, the behavior is
undefined."


I know it's undefined *by standard*. But it's pretty much well defined by so many compilers out there... Can one name a compiler that issues an error at that shift operator or yields garbage or freaks out?


GCC 3, x86 (pretty uncommon, I know...)

Using your exact sample function, Max(-2, -2) gives 6,
and Max(2, 1) gives 3.

There is even a compiler warning:
gcc h.c -o h
h.c: In function `Max':
h.c:6: warning: right shift count >= width of type

Can you name one compiler that does operate your code correctly,
out of interest?


Oops, I'm sorry, I obviously meant a right shift by *31*, not 32:

#define BITS_IN_LONG 32

long Max(long x, long y)
{
long res;
res = (x-y) >> (BITS_IN_LONG-1); /* res=0 (all zeroes) or -1 (all ones) */
res = (x & ~res) | (y & res); /* depending on prev value of res, we just
select/multiplex x or y by means of bitwise masking */
return res;
}

That works just fine on gcc 3.3.4 on x86 and gives for your pairs of
numbers:
-2
2

Compiles w/o a warning with -Wall.

Alex
Nov 15 '05 #39

Alexei A. Frounze wrote:
"Krishanu Debnath" <kr**************@gmail.com> wrote in message
news:11**********************@g47g2000cwa.googlegr oups.com...
...
[x0030819 dcesparc017 SunOS c]: cat nonsense.c
#include<limits.h>
#include<stdio.h>

int main()
{
int number = -4;
number = number >> ( CHAR_BIT * sizeof number);
I did not mean the issue with the shift amount. What's the output if you

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^
No, my crystal ball is not on strike, actuall I don't have any. I can
only
infer from what you have posted. The whole objection came up with the
shift
expression where value of the RHS is same as the width of the LHS.

Okay, I just saw your reply on Old Wolf's post. You almost took 24 hr
to
realize this.
just shift by *1* position?

Alex


Krishanu

Nov 15 '05 #40
"Krishanu Debnath" <kr**************@gmail.com> wrote in message
news:11**********************@z14g2000cwz.googlegr oups.com...
Alexei A. Frounze wrote:
"Krishanu Debnath" <kr**************@gmail.com> wrote in message ....
number = number >> ( CHAR_BIT * sizeof number);


I did not mean the issue with the shift amount. What's the output if you

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^
No, my crystal ball is not on strike, actuall I don't have any. I can
only
infer from what you have posted. The whole objection came up with the
shift
expression where value of the RHS is same as the width of the LHS.

Okay, I just saw your reply on Old Wolf's post. You almost took 24 hr
to realize this.


That's because I was thought I wrote 31 (done that many times before) and
even didn't bother to look at the code to make sure it was indeed 31. And
what's worst I used old Borland compiler that ate the source and produced
executable that gave me what I was expecting. :) Sorry, it was
unintentional.

Alex
Nov 15 '05 #41
In article <11*************@corp.supernews.com>, Gordon Burditt wrote:
It's as illogical as the need to cast one of two
integer multipliers to long integer in order to get the correct long integer
product.


I don't agree that the cast is illogical. And dealing with this
doesn't have to generate inefficient code in the cases where it's
NOT needed, unlike the shift case, which slows down all variable shifts.


it's not possible to determine what type the product should have in all
situations

#include <stdio.h>
int foo(const char * s, int a, int b,int c)
{
printf(%s,a*b,c);
}

So is it needed or not above, the type used for the expression a*b will
have a direct bearing on the behavior of the printf call...
Bye.
Jasen
Nov 15 '05 #42
In article <3l*************@individual.net>, Alexei A. Frounze wrote:
That all is correct, no doubt, however, my personal opinion is that that's
wrong to take the shift count and blindly feed it to the asm instruction
with such a limitation. It's as illogical as the need to cast one of two
integer multipliers to long integer in order to get the correct long integer
product. That strikes the math guys in the back. Anyway, I was talking about
a slightly different problem of the shift -- whether or not it's SAR-like or
something else, especially something very odd, probably not any kind of
shift at all.


C is defined to compile to efficient assembler code on a wide range of
hardware, for this reason if you step outside of the standard you may
get unexpected behavior.

if you want a language that behaves predictably in all situations C isn't it.
maybe you could try java :)

Bye.
Jasen
Nov 15 '05 #43
"Jasen Betts" <ja***@clunker.homenet> wrote in message
news:slrndf3s7d.8rs.ja***@clunker.homenet...
In article <3l*************@individual.net>, Alexei A. Frounze wrote:
That all is correct, no doubt, however, my personal opinion is that that's wrong to take the shift count and blindly feed it to the asm instruction
with such a limitation. It's as illogical as the need to cast one of two
integer multipliers to long integer in order to get the correct long integer product. That strikes the math guys in the back. Anyway, I was talking about a slightly different problem of the shift -- whether or not it's SAR-like or something else, especially something very odd, probably not any kind of
shift at all.
C is defined to compile to efficient assembler code on a wide range of
hardware,


These days the compilers do a good work. And it wasn't a question of
performance, rather of correctness.
for this reason if you step outside of the standard you may
get unexpected behavior.
To me unexpected is to get a wrong value, just the lower bits of the correct
one, even when "lvalue" is big enough to hold the correct one. But the
standard requires me to put the silly cast in or I'm in trouble of not
getting such simple thing as product of integers. IMO, in case when the
calculations may give more bits than the operands the compiler should
compile in such a way so as not to loose a single bit somewhere in the
middle. I consider the C requirement we're talking about here be broken.
It's an HLL and as such is supposed to help write better code quicker, to
implement the math (and other) algorithms in a form of machine code, but it
stumbles on integers. What a surprise to every new C programmer. :)
if you want a language that behaves predictably in all situations C isn't it. maybe you could try java :)


No, thanks. :) Somehow, I think java won't help me to get certain things
done, instead it'll make it impossible to do them at all.
Alex
Nov 15 '05 #44
In article <3l*************@individual.net>,
Alexei A. Frounze <al*****@chat.ru> wrote:
To me unexpected is to get a wrong value, just the lower bits of the correct
one, even when "lvalue" is big enough to hold the correct one. But the
standard requires me to put the silly cast in or I'm in trouble of not
getting such simple thing as product of integers. IMO, in case when the
calculations may give more bits than the operands the compiler should
compile in such a way so as not to loose a single bit somewhere in the
middle. I consider the C requirement we're talking about here be broken.
It's an HLL and as such is supposed to help write better code quicker, to
implement the math (and other) algorithms in a form of machine code, but it
stumbles on integers. What a surprise to every new C programmer. :)

for (i=1, x=1; i <1000; i++) x *= i;

Now, what size is x afterwards?
Do you realize that you are proposing that the compiler must use
a "bignum" package for all integral arithmetic, so as to be able to handle
arbitrary precision arithmetic? Consider that long * long
has the potential for producing a value which is up to
2 * CHAR_BIT * sizeof long bits wide (e.g., something that would
take a 'long long' to represent, except C89 has no 'long long'.)

It is legal in C for
sizeof char == sizeof short == sizeof int == sizeof long
i.e., there might only -be- one size of integral value, which is
fine in C89 if that value is at least 32 bits wide.

If your proposal were to carry, then unless indefinite precision
were to be required, then addition, subtraction and multiplication
would all have to be prohibitted (unless the compiler were to
insert size tests around each operation... and what's it supposed
to do if one of those tests fails??)

--
"No one has the right to destroy another person's belief by
demanding empirical evidence." -- Ann Landers
Nov 15 '05 #45
"Walter Roberson" <ro******@ibd.nrc-cnrc.gc.ca> wrote in message
news:dc**********@canopus.cc.umanitoba.ca...
In article <3l*************@individual.net>,
Alexei A. Frounze <al*****@chat.ru> wrote:
To me unexpected is to get a wrong value, just the lower bits of the correctone, even when "lvalue" is big enough to hold the correct one. But the
standard requires me to put the silly cast in or I'm in trouble of not
getting such simple thing as product of integers. IMO, in case when the
calculations may give more bits than the operands the compiler should
compile in such a way so as not to loose a single bit somewhere in the
middle. I consider the C requirement we're talking about here be broken.
It's an HLL and as such is supposed to help write better code quicker, to
implement the math (and other) algorithms in a form of machine code, but itstumbles on integers. What a surprise to every new C programmer. :)

for (i=1, x=1; i <1000; i++) x *= i;

Now, what size is x afterwards?


The same as before. :)
Do you realize that you are proposing that the compiler must use
a "bignum" package for all integral arithmetic, so as to be able to handle
arbitrary precision arithmetic?
No, I am not suggesting *that*. What I want is to do this kind of stuff
safely:
int x=something, y=something;
long z = x * y;
w/o a cast of either x or y to long. Just that sort of thing.
Consider that long * long
has the potential for producing a value which is up to
2 * CHAR_BIT * sizeof long bits wide (e.g., something that would
take a 'long long' to represent, except C89 has no 'long long'.)

It is legal in C for
sizeof char == sizeof short == sizeof int == sizeof long
i.e., there might only -be- one size of integral value, which is
fine in C89 if that value is at least 32 bits wide.
That's fine to have them all identical if the CPU supports only one
type/size of integer, however awkward that CPU can be (e.g. having strictly
32(64) bit ALU).
If your proposal were to carry, then unless indefinite precision
were to be required, then addition, subtraction and multiplication
would all have to be prohibitted (unless the compiler were to
insert size tests around each operation... and what's it supposed
to do if one of those tests fails??)


The compiler *knows* the sizes of the types, so, there's nothing to check.
Likewise, if I were to
int x=something, y=something;
long z = x + y;
I'd like to get the result w/o overflow/underflow since the result can fit
in z (provided, of course, sizeof(long)>sizeof(int), but that's a different
story IMO).

Alex
Nov 15 '05 #46
"Alexei A. Frounze" <al*****@chat.ru> writes:
"Walter Roberson" <ro******@ibd.nrc-cnrc.gc.ca> wrote in message
news:dc**********@canopus.cc.umanitoba.ca...

[...]
Do you realize that you are proposing that the compiler must use
a "bignum" package for all integral arithmetic, so as to be able to handle
arbitrary precision arithmetic?


No, I am not suggesting *that*. What I want is to do this kind of stuff
safely:
int x=something, y=something;
long z = x * y;
w/o a cast of either x or y to long. Just that sort of thing.


So you want the evaluation of an expression, particularly the type of
the expression, to be influenced by its context. In this case, you
want x * y to be evaluated as type long (either by promoting the
operands or by using an int*int-->long operation) because the result
is assigned to a variable of type long.

That's not entirely unreasonable, and there are languages that do that
kind of thing.

The advantage of the C approach is that it's simpler once you
understand it. It can be counterintuitive if you approach expressions
mathematically, but it's relatively easy to describe (no special rules
for how the context affects expression evaluation) *and* easy to work
around when you need different behavior.

I suspect that whatever rules you set up, there are going to be cases
where the result is counterintuitive.

I also suspect there's no way to change the C evaluation rules without
breaking existing code, which means no such change will ever happen,
even if the result might be a better language.

--
Keith Thompson (The_Other_Keith) 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.
Nov 15 '05 #47
"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
"Alexei A. Frounze" <al*****@chat.ru> writes:
"Walter Roberson" <ro******@ibd.nrc-cnrc.gc.ca> wrote in message
news:dc**********@canopus.cc.umanitoba.ca... [...]
Do you realize that you are proposing that the compiler must use
a "bignum" package for all integral arithmetic, so as to be able to handle arbitrary precision arithmetic?


No, I am not suggesting *that*. What I want is to do this kind of stuff
safely:
int x=something, y=something;
long z = x * y;
w/o a cast of either x or y to long. Just that sort of thing.


So you want the evaluation of an expression, particularly the type of
the expression, to be influenced by its context. In this case, you
want x * y to be evaluated as type long (either by promoting the
operands or by using an int*int-->long operation) because the result
is assigned to a variable of type long.


Right.
That's not entirely unreasonable, and there are languages that do that
kind of thing.
If I'm not mistaken, that's what Pascal does... Wait a minute, a test
program for TurboPascal shows this same problem and this same workaround
through casting. I thought it's only C's prob...
The advantage of the C approach is that it's simpler once you
understand it.
I understand it, but I'm not sure where exactly it's simpler. :)
It can be counterintuitive if you approach expressions
mathematically,
That's what I'd like to have. And btw, many ASMs (which aren't HLLs) have a
multiplication instruction that gives me what I want and my only job to save
the result in a big enough variable after this MUL. Of course, there are
others, like pairs of instructions that calculate the halves (LSB/W/* and
MSB/W/*) of the product (there are such in MMX subset). But it seems to me
that most of the times the full product is achieved through one simple
instruction.
but it's relatively easy to describe (no special rules
for how the context affects expression evaluation) *and* easy to work
around when you need different behavior.
I don't need different.
I suspect that whatever rules you set up, there are going to be cases
where the result is counterintuitive.
Example?
I also suspect there's no way to change the C evaluation rules without
breaking existing code, which means no such change will ever happen,
even if the result might be a better language.


No doubt. :)

Thanks,
Alex
Nov 15 '05 #48
[Regarding a multiply of the form N-bits x N-bits => 2N-bits]

In article <3l*************@individual.net>
Alexei A. Frounze <al*****@chat.ru> wrote:
.... And btw, many ASMs (which aren't HLLs) have a multiplication
instruction that gives me what I want and my only job to save
the result in a big enough variable after this MUL. Of course, there are
others, like pairs of instructions that calculate the halves (LSB/W/* and
MSB/W/*) of the product (there are such in MMX subset). But it seems to me
that most of the times the full product is achieved through one simple
instruction.


I am reasonably conversant in a few machine instruction sets (x86,
SPARC, VAX, 680x0, MIPS), and can do some work in about a dozen
more. I would say that machines that deliver the full 2N-bit result
are only about half as common as those that produce only the N-bit
low-order result -- although some machines (e.g., VAX) have some
way (often a separate, slower instruction) to produce the full
2N-bit result.

MIPS (at least as of R2000/R3000; they may have changed this in the
R4000) is unusual in having all multiplies produce their results in
the special "multiply result" register-pair, making it easy to get
either the N-bit result with one instruction (read multiplier-lo), or
the 2N-bit result with two (read multiplier-lo and multiplier-hi).

SPARC originally had no multiply at all (only "multiply step", from
which one synthesized multiply, using the special %y register) but
acquired multiply instructions in V8 and V9. The multiply
instructions deliver only an N-bit result. Using %y you can do
a 32x32 => 64 multiply, but on V9, %y remains 32 bits, so you
cannot obtain the 64x64 => 128 result with a single instruction.

The "quad" library I wrote for 4.4BSD includes code to compute 32
x 32 => 64 bit results (well, "half-quad x half-quad => full-quad"
-- it will do 64x64 => 128 if the number of bits in a quad is 128).
The code is fairly short, so here it is. Note that the function
name is that used by GCC and is in the implementor's namespace.

(The quad routines also include Knuth's Algorithm D for division,
optimized again for 64-bit divisor / 64-bit dividend => 64-bit
quotient with 64-bit remainder. As with the multiply code, I
attempted to parameterize it so that "32 bits" and "64 bits" are
not assumed, but this is the only way it has been used.)

/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This software was developed by the Computer Systems Engineering group
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
* contributed to Berkeley.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/

#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)muldi3.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */

#include "quad.h"

/*
* Multiply two quads.
*
* Our algorithm is based on the following. Split incoming quad values
* u and v (where u,v >= 0) into
*
* u = 2^n u1 * u0 (n = number of bits in `u_long', usu. 32)
*
* and
*
* v = 2^n v1 * v0
*
* Then
*
* uv = 2^2n u1 v1 + 2^n u1 v0 + 2^n v1 u0 + u0 v0
* = 2^2n u1 v1 + 2^n (u1 v0 + v1 u0) + u0 v0
*
* Now add 2^n u1 v1 to the first term and subtract it from the middle,
* and add 2^n u0 v0 to the last term and subtract it from the middle.
* This gives:
*
* uv = (2^2n + 2^n) (u1 v1) +
* (2^n) (u1 v0 - u1 v1 + u0 v1 - u0 v0) +
* (2^n + 1) (u0 v0)
*
* Factoring the middle a bit gives us:
*
* uv = (2^2n + 2^n) (u1 v1) + [u1v1 = high]
* (2^n) (u1 - u0) (v0 - v1) + [(u1-u0)... = mid]
* (2^n + 1) (u0 v0) [u0v0 = low]
*
* The terms (u1 v1), (u1 - u0) (v0 - v1), and (u0 v0) can all be done
* in just half the precision of the original. (Note that either or both
* of (u1 - u0) or (v0 - v1) may be negative.)
*
* This algorithm is from Knuth vol. 2 (2nd ed), section 4.3.3, p. 278.
*
* Since C does not give us a `long * long = quad' operator, we split
* our input quads into two longs, then split the two longs into two
* shorts. We can then calculate `short * short = long' in native
* arithmetic.
*
* Our product should, strictly speaking, be a `long quad', with 128
* bits, but we are going to discard the upper 64. In other words,
* we are not interested in uv, but rather in (uv mod 2^2n). This
* makes some of the terms above vanish, and we get:
*
* (2^n)(high) + (2^n)(mid) + (2^n + 1)(low)
*
* or
*
* (2^n)(high + mid + low) + low
*
* Furthermore, `high' and `mid' can be computed mod 2^n, as any factor
* of 2^n in either one will also vanish. Only `low' need be computed
* mod 2^2n, and only because of the final term above.
*/
static quad_t __lmulq(u_long, u_long);

quad_t
__muldi3(a, b)
quad_t a, b;
{
union uu u, v, low, prod;
register u_long high, mid, udiff, vdiff;
register int negall, negmid;
#define u1 u.ul[H]
#define u0 u.ul[L]
#define v1 v.ul[H]
#define v0 v.ul[L]

/*
* Get u and v such that u, v >= 0. When this is finished,
* u1, u0, v1, and v0 will be directly accessible through the
* longword fields.
*/
if (a >= 0)
u.q = a, negall = 0;
else
u.q = -a, negall = 1;
if (b >= 0)
v.q = b;
else
v.q = -b, negall ^= 1;

if (u1 == 0 && v1 == 0) {
/*
* An (I hope) important optimization occurs when u1 and v1
* are both 0. This should be common since most numbers
* are small. Here the product is just u0*v0.
*/
prod.q = __lmulq(u0, v0);
} else {
/*
* Compute the three intermediate products, remembering
* whether the middle term is negative. We can discard
* any upper bits in high and mid, so we can use native
* u_long * u_long => u_long arithmetic.
*/
low.q = __lmulq(u0, v0);

if (u1 >= u0)
negmid = 0, udiff = u1 - u0;
else
negmid = 1, udiff = u0 - u1;
if (v0 >= v1)
vdiff = v0 - v1;
else
vdiff = v1 - v0, negmid ^= 1;
mid = udiff * vdiff;

high = u1 * v1;

/*
* Assemble the final product.
*/
prod.ul[H] = high + (negmid ? -mid : mid) + low.ul[L] +
low.ul[H];
prod.ul[L] = low.ul[L];
}
return (negall ? -prod.q : prod.q);
#undef u1
#undef u0
#undef v1
#undef v0
}

/*
* Multiply two 2N-bit longs to produce a 4N-bit quad, where N is half
* the number of bits in a long (whatever that is---the code below
* does not care as long as quad.h does its part of the bargain---but
* typically N==16).
*
* We use the same algorithm from Knuth, but this time the modulo refinement
* does not apply. On the other hand, since N is half the size of a long,
* we can get away with native multiplication---none of our input terms
* exceeds (ULONG_MAX >> 1).
*
* Note that, for u_long l, the quad-precision result
*
* l << N
*
* splits into high and low longs as HHALF(l) and LHUP(l) respectively.
*/
static quad_t
__lmulq(u_long u, u_long v)
{
u_long u1, u0, v1, v0, udiff, vdiff, high, mid, low;
u_long prodh, prodl, was;
union uu prod;
int neg;

u1 = HHALF(u);
u0 = LHALF(u);
v1 = HHALF(v);
v0 = LHALF(v);

low = u0 * v0;

/* This is the same small-number optimization as before. */
if (u1 == 0 && v1 == 0)
return (low);

if (u1 >= u0)
udiff = u1 - u0, neg = 0;
else
udiff = u0 - u1, neg = 1;
if (v0 >= v1)
vdiff = v0 - v1;
else
vdiff = v1 - v0, neg ^= 1;
mid = udiff * vdiff;

high = u1 * v1;

/* prod = (high << 2N) + (high << N); */
prodh = high + HHALF(high);
prodl = LHUP(high);

/* if (neg) prod -= mid << N; else prod += mid << N; */
if (neg) {
was = prodl;
prodl -= LHUP(mid);
prodh -= HHALF(mid) + (prodl > was);
} else {
was = prodl;
prodl += LHUP(mid);
prodh += HHALF(mid) + (prodl < was);
}

/* prod += low << N */
was = prodl;
prodl += LHUP(low);
prodh += HHALF(low) + (prodl < was);
/* ... + low; */
if ((prodl += low) < low)
prodh++;

/* return 4N-bit product */
prod.ul[H] = prodh;
prod.ul[L] = prodl;
return (prod.q);
}
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 15 '05 #49
cs
On 6 Aug 2005 16:28:43 GMT, Chris Torek <no****@torek.net> wrote:
[Regarding a multiply of the form N-bits x N-bits => 2N-bits]


for me it could be <10 of assembly lines for each cpu
Nov 15 '05 #50

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

Similar topics

3
2968
by: Chris Mantoulidis | last post by:
I posted this here one day ago but it seems like it hasn't been put up for some unknown reason. That gives me a chance to say things a bit better in this post. 1st of all let's desribe the...
108
6298
by: Bryan Olson | last post by:
The Python slice type has one method 'indices', and reportedly: This method takes a single integer argument /length/ and computes information about the extended slice that the slice object would...
5
3001
by: Mike Labosh | last post by:
In VB 6, the Form_QueryUnload event had an UnloadMode parameter that let me find out *why* a form is unloading, and then conditionally cancel the event. In VB.NET, the Closing event passes a...
3
7178
by: DJTN | last post by:
I'm getting the following error when I try to compile my setup project in VS 2002. I have re-installed the .net framework 1.1 and it didnt solve the problem. WARNING: Unable to find dependency...
9
2109
by: Tony Girgenti | last post by:
Hello. I'm developing and testing a web application using VS.NET 2003, VB, .NET Framework 1.1.4322, ASP.NET 1.1.4322 and IIS5.1 on a WIN XP Pro, SP2 computer. I'm using a web form. For a...
1
1519
by: TheScullster | last post by:
Hi all Bit of an obscure one this, but hopefully someone will be able to help. 4 years ago we had a potentially catastrophic problem with our Access database. From memory it was written in...
11
3679
by: Ko van der Sloot | last post by:
Hello I was wondering which behaviour might be expected (or is required) for the following small program. I would expect that find( "a", string::npos ) would return string::npos but is seems to...
2
2643
by: moondaddy | last post by:
I had to repost this because I had to update and change my msdn alias. I will re-ask the question and clarify a few things that were not clear before. This code is all executed on my dev...
9
3432
by: JoeP | last post by:
Hi All, How can I find the reason for such an error: Failure sending mail. Some Code... oMailMessage.IsBodyHtml = False oMailMessage.Body = cEmailBody Dim oSMTP As New SmtpClient...
0
22420
by: zephyrus360 | last post by:
This is about a technique to find the mod of a very large integer with a normal small integer. I recently encountered this problem when I needed to compute the modulus of a very large number with...
0
7194
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,...
0
7070
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7267
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,...
0
5566
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,...
1
4993
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...
0
4666
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...
0
3160
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...
1
729
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
372
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...

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.