S
sabarish
Hi to all. find out the biggest among two numbers without using any
conditional statements and any relational operators.
conditional statements and any relational operators.
sabarish said:Hi to all. find out the biggest among two numbers without using any
conditional statements and any relational operators.
Eric Sosman said: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.
sabarish said:Hi to all. find out the biggest among two numbers without using any
conditional statements and any relational operators.
result=(x-y) //subtract y from x
//if x>y result is +ve else -ve
sabarish said:Hi to all. find out the biggest among two numbers without using any
conditional statements and any relational operators.
Richard said:No, they don't. Check the OED.
What you describe is merely customary in
some circles, but not the only correct usage.
sabarish said:Hi to all. find out the biggest among two numbers without using any
conditional statements and any relational operators.
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
akarl said:It's simple as well as off topic (since it's not C specific):
max(x, y) = (x + y + |x - y|) / 2
sabarish said:Hi to all. find out the biggest among two numbers without using any
conditional statements and any relational operators.
Eric said:sabarish wrote:
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).
Keith Thompson said:That has so many portability problems I'm not going to bother to
decide whether it's correct.
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
Alexei said:[snip]Keith Thompson said:(e-mail address removed) writes:
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;
}
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).
For a specific example: Intel Pentium, gcc 3.4.2 on FreeBSD. A
[snippy-snip]
int main(void)
{
x(36);
x(32);
> The output (annotated to the right):
> 36: 1234567 Same as a shift of 4
> 32: 12345678 Same as no shift at all
> 0: 12345678
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.
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
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.