I am looking for other ways to write the following in as few lines as
possible, but I think I have hit the limit...
x -= x/abs(x)
So far, I have come up with this(it seems to work anyway):
x -= x > 0 ? 1 : -1
Can anyone see any other way of expressing this as a single expression?
Corvus
--
Meh
|
|
0
|
|
|
|
Reply
|
noway540 (3)
|
10/22/2009 4:40:10 AM |
|
"Corvus" <noway@goaway.com> wrote in message
news:JmRDm.730$aD1.689@newsfe19.iad...
>I am looking for other ways to write the following in as few lines as
>possible, but I think I have hit the limit...
>
> x -= x/abs(x)
>
> So far, I have come up with this(it seems to work anyway):
>
> x -= x > 0 ? 1 : -1
>
> Can anyone see any other way of expressing this as a single expression?
>
x -= 1-((!(x>0))<<1);
or, do you mean "sensible"?...
> Corvus
>
> --
> Meh
|
|
0
|
|
|
|
Reply
|
cr88192355 (1754)
|
10/22/2009 4:53:23 AM
|
|
Corvus wrote:
> I am looking for other ways to write the following in as few lines as
> possible, but I think I have hit the limit...
>
> x -= x/abs(x)
>
> So far, I have come up with this(it seems to work anyway):
>
> x -= x > 0 ? 1 : -1
>
> Can anyone see any other way of expressing this as a single expression?
Ignoring the case x == 0, assuming it is an int type, as you have done:
x += 1 - 2*(x>0);
(x>0)? x-- : x++ ;
.....
Before 1975, there were practical languages with few alternate syntactic
choices for the same result, but C put an end to that.
|
|
0
|
|
|
|
Reply
|
tprince (585)
|
10/22/2009 5:02:10 AM
|
|
BGB / cr88192 wrote:
> "Corvus" <noway@goaway.com> wrote in message
> news:JmRDm.730$aD1.689@newsfe19.iad...
>> I am looking for other ways to write the following in as few lines as
>> possible, but I think I have hit the limit...
>>
>> x -= x/abs(x)
>>
>> So far, I have come up with this(it seems to work anyway):
>>
>> x -= x > 0 ? 1 : -1
>>
>> Can anyone see any other way of expressing this as a single expression?
>>
>
>
> x -= 1-((!(x>0))<<1);
>
> or, do you mean "sensible"?...
>
>
>> Corvus
>>
>> --
>> Meh
>
>
Interesting...I honestly had never thought of that...and no, it doesn't
have to be sensible. :-)
Corvus
|
|
0
|
|
|
|
Reply
|
noway540 (3)
|
10/22/2009 5:02:36 AM
|
|
Tim Prince wrote:
> Corvus wrote:
>> I am looking for other ways to write the following in as few lines as
>> possible, but I think I have hit the limit...
>>
>> x -= x/abs(x)
>>
>> So far, I have come up with this(it seems to work anyway):
>>
>> x -= x > 0 ? 1 : -1
>>
>> Can anyone see any other way of expressing this as a single expression?
>
> Ignoring the case x == 0, assuming it is an int type, as you have done:
> x += 1 - 2*(x>0);
> (x>0)? x-- : x++ ;
> ....
> Before 1975, there were practical languages with few alternate syntactic
> choices for the same result, but C put an end to that.
Nice...!
|
|
0
|
|
|
|
Reply
|
noway540 (3)
|
10/22/2009 5:06:18 AM
|
|
On Oct 22, 12:40=A0pm, Corvus <no...@goaway.com> wrote:
> I am looking for other ways to write the following in as few lines as
> possible, but I think I have hit the limit...
>
> x -=3D x/abs(x)
>
> So far, I have come up with this(it seems to work anyway):
>
> x -=3D x > 0 ? 1 : -1
>
> Can anyone see any other way of expressing this as a single expression?
>
> Corvus
>
> --
> Meh
Your solutions all have a bug: what if x is zero? Don't optimize until
you've debugged.
It appears that you are trying to calculate the value of the signum
function, which is NOT -1 for zero, nor undefined. Signum is 1 for x >
0, 0 for x=3D=3D0, -1 for x < 0.
Do it straightforwardly:
x -=3D x > 0 ? 1 : (x < 0 ? -1 : 0)
A more reliable way would be to package it as a function, and, in the
function, test x for all possible values. In the most general case, x
does not have to be positive, negative or zero: in a weakly typed OO
system it might be a complex number.
x -=3D signum(x)
float signum(int x)
{
if (x > 0) return 1;
if (x < 0) return -1;
if (x =3D=3D 0) return 0;
printf("Fatal error, alack the day\n");
}
Of course, in the above, x's being an int guarantees that the last
test is unnecessary, but not in the most general case. For reliability
it never hurts, when classifying something, to explicitly test it for
all possible cases rather than "falling through" to a "default" value;
note that the shift into traditional "programmerese" is a signal that
we're about to revert to barbarism as is also the case when a
programmer starts raving about "buffers": when programmers talk about
"falling through" they mean "I am probably missing something, and
indeed I feel like Alice in the rabbit hole".
I wouldn't use the third test in implementing signum if it can declare
its parameter as one of short, int, long, float or double because in
each case, the runtime, including the famous goddamn stack, guarantees
that x will be zero when not positive or negative...
....except (and this is important, so wake the Christ up) in certain
floating point applications where it might make perfect sense to do
this: I can easily imagine some goddamn scenario where float or double
x is not greater than, less than, or equal to zero, and code inserted
by some slob to catch this when it happens on alternate Tuesdays
during a gibbous moon.
Of course, the fun rilly starts when you implement SIGNUM, a macro: oh
dearie me how did I do that:
#define SIGNUM(x) ((x) > 0 ? 1 : ((x) < 0 ? -1 : 0))
(Ben Bacarisse will probably find ten real bugs in the above macro).
This macro should probably test for all three possibilities since we
have absolutely no idea what x is!
#define SIGNUM(x) ((x) > 0 ? 1 : ((x) < 0 ? -1 : ((x) =3D=3D 0 ? 0 :
errorHandling())))
There probably are also ways of punning on the representation of
Boolean values as numbers:
#define SIGNUM(x) (x) ? ((x) > 0 ? 1 : -1) : 0
oh gee that saves one jillionth of a terapicosecond.
The best solution? Find a complete math library which defines signum.
|
|
0
|
|
|
|
Reply
|
spinoza1111 (3250)
|
10/22/2009 6:28:03 AM
|
|
On Oct 22, 1:02=A0pm, Tim Prince <tpri...@nospamcomputer.org> wrote:
> Corvus wrote:
> > I am looking for other ways to write the following in as few lines as
> > possible, but I think I have hit the limit...
>
> > x -=3D x/abs(x)
>
> > So far, I have come up with this(it seems to work anyway):
>
> > x -=3D x > 0 ? 1 : -1
>
> > Can anyone see any other way of expressing this as a single expression?
>
> Ignoring the case x =3D=3D 0, assuming it is an int type, as you have don=
e:
"Ignoring the case where x=3D=3D0" is a bug waiting to strike. It appears
to me that nobody told the OP that in statistics and other math,
signum is zero when x is zero.
> x +=3D 1 - 2*(x>0);
> (x>0)? x-- : x++ ;
> ....
> Before 1975, there were practical languages with few alternate syntactic
> choices for the same result, but C put an end to that.
|
|
0
|
|
|
|
Reply
|
spinoza1111 (3250)
|
10/22/2009 6:29:26 AM
|
|
Corvus <noway@goaway.com> writes:
> I am looking for other ways to write the following in as few lines as
> possible, but I think I have hit the limit...
>
> x -= x/abs(x)
>
> So far, I have come up with this(it seems to work anyway):
>
> x -= x > 0 ? 1 : -1
Note that these are not equivalent; when x == 0, the first invokes
undefined behavior, and the second sets x to 1.
> Can anyone see any other way of expressing this
if (x > 0) {
--x;
}
else {
--x;
}
> as a single expression?
Um, why do you want it as a single expression? It's not likely to be
either clearer or more efficient.
If you insist, you could write it as:
x > 0 ? --x : ++x;
but it's likely to generate the same code.
Rule of thumb: If a ?: operator can be written equivalently as an
if-else statement, write it as an if-else statement (unless it's
part of a macro definition).
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
|
|
0
|
|
|
|
Reply
|
kst-u (21469)
|
10/22/2009 6:51:09 AM
|
|
On Oct 22, 2:51=A0pm, Keith Thompson <ks...@mib.org> wrote:
> Corvus <no...@goaway.com> writes:
> > I am looking for other ways to write the following in as few lines as
> > possible, but I think I have hit the limit...
>
> > x -=3D x/abs(x)
>
> > So far, I have come up with this(it seems to work anyway):
>
> > x -=3D x > 0 ? 1 : -1
>
> Note that these are not equivalent; when x =3D=3D 0, the first invokes
> undefined behavior, and the second sets x to 1.
>
> > Can anyone see any other way of expressing this
>
> if (x > 0) {
> =A0 =A0 --x;}
>
> else {
> =A0 =A0 --x;
>
> }
> > as a single expression?
>
> Um, why do you want it as a single expression? =A0It's not likely to be
> either clearer or more efficient.
>
> If you insist, you could write it as:
>
> =A0 =A0 x > 0 ? --x : ++x;
>
> but it's likely to generate the same code.
>
> Rule of thumb: If a ?: operator can be written equivalently as an
> if-else statement, write it as an if-else statement (unless it's
> part of a macro definition).
>
Thumb of rule: ignore the bug while helping the guy implement signum
incorrectly. I believe that he is implementing something where the
user wants signum and x may be zero, where the function should return
zero, but nobunny has told him this.
Also, I would question whether it's clearer to use if then else
than ?:. Granted the syntax is pretty much unique to C, but much worse
is unique to C. Using ?: shows awareness that while mathematics is not
part of logic, logic is part of mathematics.
A pragmatic argument for using C "statements" in place of C
"expressions" would be that on primitive debuggers it is easier to
step through complicated logic. But many modern debuggers allow
stepthrough of expressions as well, and debugging needs should not
control.
> --
> Keith Thompson (The_Other_Keith) ks...@mib.org =A0<http://www.ghoti.net/~=
kst>
> Nokia
> "We must do something. =A0This is something. =A0Therefore, we must do thi=
s."
> =A0 =A0 -- Antony Jay and Jonathan Lynn, "Yes Minister"
|
|
0
|
|
|
|
Reply
|
spinoza1111 (3250)
|
10/22/2009 8:43:39 AM
|
|
Corvus <noway@goaway.com> writes:
>I am looking for other ways to write the following in as few
>lines as possible, but I think I have hit the limit...
>x -= x/abs(x)
>x -= x > 0 ? 1 : -1
One line is a natural limit for the size of an expression,
because the only text with fewer lines is the empty text ��,
but this is not an expression. So you can not write an
expression with less than at least one line.
However, you might be able to reduce the number of lines
an expression takes by adding a comment:
x -= x/abs(x) ////////////////////////////////////////////////
. Now the expression only takes about 0.25 lines, that is,
less than one line, because about 75 percent of the line are
being filled with the comment.
|
|
0
|
|
|
|
Reply
|
ram (2827)
|
10/22/2009 9:08:50 AM
|
|
"Corvus" <noway@goaway.com> wrote in message
news:JmRDm.730$aD1.689@newsfe19.iad...
>I am looking for other ways to write the following in as few lines as
>possible, but I think I have hit the limit...
>
> x -= x/abs(x)
>
> So far, I have come up with this(it seems to work anyway):
>
> x -= x > 0 ? 1 : -1
>
> Can anyone see any other way of expressing this as a single expression?
Both your examples are already single expressions, and are already expressed
in a single line.
Is x an int or float? If it's an int, and the range of values is known to be
small, you can use a table which maps x to x/abs(x), then use:
x = table[x]
The table can also take care of x==0. While the table will take up
additional lines, it means you can use a simpler assignment, if that was the
idea.
For unknown ranges of ints, it seems your code just increments or decrements
x towards 0. If x is not assigned to elsewhere, you can use an extra
variable like this:
dx = x<0 ? 1 : -1
Then you can just use this, assuming it's in some kind of loop:
x += dx
although you have to figure out what to do when x reaches zero.
--
Bartc
|
|
0
|
|
|
|
Reply
|
bartc (783)
|
10/22/2009 10:18:10 AM
|
|
Keith Thompson <kst-u@mib.org> writes:
> Corvus <noway@goaway.com> writes:
>> I am looking for other ways to write the following in as few lines as
>> possible, but I think I have hit the limit...
>>
>> x -= x/abs(x)
>>
>> So far, I have come up with this(it seems to work anyway):
>>
>> x -= x > 0 ? 1 : -1
>
> Note that these are not equivalent; when x == 0, the first invokes
> undefined behavior, and the second sets x to 1.
Also, the former is undefined if abs(x) can't be represented which is
a practical concern on many machines when x == INT_MIN.
<snip>
--
Ben.
|
|
0
|
|
|
|
Reply
|
ben.usenet (6515)
|
10/22/2009 10:38:03 AM
|
|
On Oct 22, 1:51=A0pm, Keith Thompson <ks...@mib.org> wrote:
>
> Rule of thumb: If a ?: operator can be written equivalently as an
> if-else statement, write it as an if-else statement (unless it's
> part of a macro definition).
I think we'd all agree that "cutesy" shortcuts to achieve a
false keystroke economy are wrong, but this statement goes much
too far. It seems to assume that "if else" is more readable
than "? :" but that should *not* be the case for a C programmer.
I often string together ?, : and/or && and || into an involved
expression, and add newlines and tabs to make it easy to read.
IMHO the if/else equivalent would be harder to read because of
all the "if/else" clutter.
Surely none of us prefer Cobol's
ADD OVERTIME TO SALARY
or whatever it is, over C's
salary +=3D overtime;
Not to extend the same courtesy to C's beautiful " ? : "
would be to patronize the beginning C programmer.
James Dow Allen
|
|
0
|
|
|
|
Reply
|
jdallen2000 (489)
|
10/22/2009 11:07:43 AM
|
|
spinoza1111 <spinoza1111@yahoo.com> writes:
>It appears that you are trying to calculate the value of the signum
>function, which is NOT -1 for zero, nor undefined. Signum is 1 for x >
>0, 0 for x==0, -1 for x < 0.
For signum,
( x > 0 )-( x < 0 )
might be efficient, because it can often be compiles to
three instructions and does not contain branches.
Unlike solutions involving "x >> 31" it does not depend on
details of the representation and is also quite readable.
|
|
0
|
|
|
|
Reply
|
ram (2827)
|
10/22/2009 11:26:52 AM
|
|
In <lines-of-expressions-20091022110353@ram.dialup.fu-berlin.de>,
Stefan Ram wrote:
> Corvus <noway@goaway.com> writes:
>>I am looking for other ways to write the following in as few
>>lines as possible, but I think I have hit the limit...
>>x -= x/abs(x)
>>x -= x > 0 ? 1 : -1
>
> One line is a natural limit for the size of an expression,
> because the only text with fewer lines is the empty text ��,
> but this is not an expression. So you can not write an
> expression with less than at least one line.
>
> However, you might be able to reduce the number of lines
> an expression takes by adding a comment:
>
> x -= x/abs(x) ////////////////////////////////////////////////
>
> . Now the expression only takes about 0.25 lines, that is,
> less than one line, because about 75 percent of the line are
> being filled with the comment.
I think this takes the prize for "Wry Grin of the Week".
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
|
|
0
|
|
|
|
Reply
|
rjh (10789)
|
10/22/2009 11:49:15 AM
|
|
On 22 Oct, 12:26, r...@zedat.fu-berlin.de (Stefan Ram) wrote:
> =A0 For signum,
>
> ( x > 0 )-( x < 0 )
>
> =A0 might be efficient, because it can often be compiles to
> =A0 three instructions and does not contain branches.
>
> =A0 Unlike solutions involving "x >> 31" it does not depend on
> =A0 details of the representation and is also quite readable.
For some values of "readable", I guess. I quite like it, but I'm not
convinced that this sort of variation on Perl Golf is helpful for real-
world code. I've debugged other people's code at 3am after spending
the evening trying to get a baby to go to sleep, and frankly I'd curse
them if their code wasn't transparent. I'm with Spinoza here - be
explicit.
|
|
0
|
|
|
|
Reply
|
mark.bluemel (71)
|
10/22/2009 12:20:13 PM
|
|
In
<e9b179a7-38c1-4e3a-87c9-0097d9c9e5a8@p20g2000vbl.googlegroups.com>,
Mark Bluemel wrote:
> On 22 Oct, 12:26, r...@zedat.fu-berlin.de (Stefan Ram) wrote:
>
>> For signum,
>>
>> ( x > 0 )-( x < 0 )
>>
>> might be efficient, because it can often be compiles to
>> three instructions and does not contain branches.
>>
>> Unlike solutions involving "x >> 31" it does not depend on
>> details of the representation and is also quite readable.
>
> For some values of "readable", I guess.
It is a most readable expression, once you get used to the notion that
relational expressions have values in their own right. (It is not
unreasonable to assume a certain level of "literacy" in the reader
when assessing readability.)
> I quite like it, but I'm not
> convinced that this sort of variation on Perl Golf is helpful for
> real- world code.
I regularly use the same idiom in real-world code, in comparison
functions, and I don't see why you would think it to be unsuitable
for the real world.
> I've debugged other people's code at 3am after
> spending the evening trying to get a baby to go to sleep, and
> frankly I'd curse them if their code wasn't transparent. I'm with
> Spinoza here
That's not absolute proof that you're wrong, but it's not a hopeful
sign.
> - be explicit.
The expression /is/ explicit.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
|
|
0
|
|
|
|
Reply
|
rjh (10789)
|
10/22/2009 12:36:47 PM
|
|
"Richard Heathfield" <rjh@see.sig.invalid> wrote in message
news:5Oqdnf0U3OL2zX3XnZ2dnUVZ8hydnZ2d@bt.com...
> In
> <e9b179a7-38c1-4e3a-87c9-0097d9c9e5a8@p20g2000vbl.googlegroups.com>,
> Mark Bluemel wrote:
>
>> On 22 Oct, 12:26, r...@zedat.fu-berlin.de (Stefan Ram) wrote:
>>
>>> For signum,
>>>
>>> ( x > 0 )-( x < 0 )
>> - be explicit.
>
> The expression /is/ explicit.
Not as explicit as, say:
intsign(x)
The original expression requires some analysis as to what it's trying to
achieve.
And if the variable name was longer, and the expression appears many times
then it requires more analysis to make sure no mistake has been made, such
as one or both of the > or < being the right way around, and the same name
was used in each half. (And if there is a discrepancy, was it a mistake, or
is it actually something unrelated.)
--
bartc
|
|
0
|
|
|
|
Reply
|
bartc (783)
|
10/22/2009 12:56:15 PM
|
|
On Oct 22, 8:36=A0pm, Richard Heathfield <r...@see.sig.invalid> wrote:
> In
> <e9b179a7-38c1-4e3a-87c9-0097d9c9e...@p20g2000vbl.googlegroups.com>,
>
> Mark Bluemel wrote:
> > On 22 Oct, 12:26, r...@zedat.fu-berlin.de (Stefan Ram) wrote:
>
> >> For signum,
>
> >> ( x > 0 )-( x < 0 )
>
> >> might be efficient, because it can often be compiles to
> >> three instructions and does not contain branches.
>
> >> Unlike solutions involving "x >> 31" it does not depend on
> >> details of the representation and is also quite readable.
>
> > For some values of "readable", I guess.
>
> It is a most readable expression, once you get used to the notion that
> relational expressions have values in their own right. (It is not
> unreasonable to assume a certain level of "literacy" in the reader
> when assessing readability.)
>
Nobody has yet conceded the main problem, that the OP is trying to
implement signum and failing by giving a **wrong answer** when x is
zero but the above solution seems to address this problem.
It's amazing that so few people here seem to know signum. Disturbing,
as well.
> > I quite like it, but I'm not
> > convinced that this sort of variation on Perl Golf is helpful for
> > real- world code.
>
> I regularly use the same idiom in real-world code, in comparison
> functions, and I don't see why you would think it to be unsuitable
> for the real world.
>
> > I've debugged other people's code at 3am after
> > spending the evening trying to get a baby to go to sleep, and
> > frankly I'd curse them if their code wasn't transparent. I'm with
> > Spinoza here
>
> That's not absolute proof that you're wrong, but it's not a hopeful
> sign.
Personality based comments are childish and have no place here. I'm
real tired of how you consistently transform technical issues into
personal icons. You have two registers: uncritical worship of some
personality (such as Ada Augusta) whose status impresses you, and
uncritical trashing when you think the target is a safe place to shit
on.
It's lower middle class and Fascistic. Cease and desist or leave on a
holiday in Spain.
>
> > - be explicit.
>
> The expression /is/ explicit.
>
> --
> Richard Heathfield <http://www.cpax.org.uk>
> Email: -http://www. +rjh@
> "Usenet is a strange place" - dmr 29 July 1999
> Sig line vacant - apply within
|
|
0
|
|
|
|
Reply
|
spinoza1111 (3250)
|
10/22/2009 1:04:06 PM
|
|
On Oct 22, 1:36=A0pm, Richard Heathfield <r...@see.sig.invalid> wrote:
> >> ( x > 0 )-( x < 0 )
>
> It is a most readable expression, once you get used to the notion that
> relational expressions have values in their own right. (It is not
> unreasonable to assume a certain level of "literacy" in the reader
> when assessing readability.)
We must have wildly different ideas about readability. To me readable
code is code that expresses intent clearly. "Programs are meant to be
read by humans and only incidentally for computers to execute".
x -=3D (x>0)-(x<0);
does not express intent clearly. One can work out what it does quite
easily, but that's still work. It's all about "how" and not about
"why".
/* ... or a macro, obviously ... */
static inline int signum (int x){
return (x>0)-(x<0);
}
/* ... */
x -=3D signum(x);
is the best of both worlds.
|
|
0
|
|
|
|
Reply
|
gwowen (518)
|
10/22/2009 1:10:58 PM
|
|
On Oct 22, 9:04=A0am, spinoza1111 <spinoza1...@yahoo.com> wrote:
> Personality based comments are childish and have no place here.
<snip>
> It's lower middle class and Fascistic. Cease and desist or leave on a
> holiday in Spain.
Pot, kettle, etc.
-David
|
|
0
|
|
|
|
Reply
|
lndresnick (326)
|
10/22/2009 1:22:02 PM
|
|
On Oct 22, 9:22=A0pm, David Resnick <lndresn...@gmail.com> wrote:
> On Oct 22, 9:04=A0am,spinoza1111<spinoza1...@yahoo.com> wrote:
>
> > Personality based comments are childish and have no place here.
> <snip>
> > It's lower middle class and Fascistic. Cease and desist or leave on a
> > holiday in Spain.
>
> Pot, kettle, etc.
>
> -David
No, it is not pot and kettle. If you sequence the posts, it is
consistently Richard Heathfield who starts the campaign of personality
destruction. I finish it and will continue to do so because "this
animal is dangerous, it defends itself when attacked."
|
|
0
|
|
|
|
Reply
|
spinoza1111 (3250)
|
10/22/2009 3:29:26 PM
|
|
In article
<d84fff93-0748-48a7-a7ad-03c353e32642@g22g2000prf.googlegroups.com>,
spinoza1111 <spinoza1111@yahoo.com> wrote:
> On Oct 22, 9:22�pm, David Resnick <lndresn...@gmail.com> wrote:
> > On Oct 22, 9:04�am,spinoza1111<spinoza1...@yahoo.com> wrote:
> >
> > > Personality based comments are childish and have no place here.
> > <snip>
> > > It's lower middle class and Fascistic. Cease and desist or leave on a
> > > holiday in Spain.
> >
> > Pot, kettle, etc.
> >
> > -David
>
> No, it is not pot and kettle. If you sequence the posts, it is
> consistently Richard Heathfield who starts the campaign of personality
> destruction. I finish it and will continue to do so because "this
> animal is dangerous, it defends itself when attacked."
So you agree you are childish, then, and that you have no place here? As
in:
On Oct 22, 9:04�am,spinoza1111<spinoza1...@yahoo.com> wrote:
> Personality based comments are childish and have no place here.
--
Tim
"That excessive bail ought not to be required, nor excessive fines imposed,
nor cruel and unusual punishments inflicted" -- Bill of Rights 1689
|
|
0
|
|
|
|
Reply
|
timstreater (943)
|
10/22/2009 3:46:00 PM
|
|
On 22 Oct, 14:10, gwowen <gwo...@gmail.com> wrote:
> On Oct 22, 1:36=A0pm, Richard Heathfield <r...@see.sig.invalid> wrote:
>
> > >> ( x > 0 )-( x < 0 )
>
> > It is a most readable expression, once you get used to the notion that
> > relational expressions have values in their own right. (It is not
> > unreasonable to assume a certain level of "literacy" in the reader
> > when assessing readability.)
>
> We must have wildly different ideas about readability. To me readable
> code is code that expresses intent clearly. "Programs are meant to be
> read by humans and only incidentally for computers to execute".
Thank you. That's pretty much what I feel. I'd kind of like to see a
book published on "expressive coding".
>
> x -=3D (x>0)-(x<0);
>
> does not express intent clearly. =A0One can work out what it does quite
> easily, but that's still work. It's all about "how" and not about
> "why".
Indeed
>
> /* ... or a macro, obviously ... */
> static inline int signum (int x){
> =A0 return (x>0)-(x<0);}
>
> /* ... */
> x -=3D signum(x);
>
> is the best of both worlds.
|
|
0
|
|
|
|
Reply
|
mark.bluemel (71)
|
10/22/2009 3:48:22 PM
|
|
On Oct 22, 11:46=A0pm, Tim Streater <timstrea...@waitrose.com> wrote:
> In article
> <d84fff93-0748-48a7-a7ad-03c353e32...@g22g2000prf.googlegroups.com>,
>
>
>
>
>
> =A0spinoza1111 <spinoza1...@yahoo.com> wrote:
> > On Oct 22, 9:22=A0pm, David Resnick <lndresn...@gmail.com> wrote:
> > > On Oct 22, 9:04=A0am,spinoza1111<spinoza1...@yahoo.com> wrote:
>
> > > > Personality based comments are childish and have no place here.
> > > <snip>
> > > > It's lower middle class and Fascistic. Cease and desist or leave on=
a
> > > > holiday in Spain.
>
> > > Pot, kettle, etc.
>
> > > -David
>
> > No, it is not pot and kettle. If you sequence the posts, it is
> > consistently Richard Heathfield who starts the campaign of personality
> > destruction. I finish it and will continue to do so because "this
> > animal is dangerous, it defends itself when attacked."
>
> So you agree you are childish, then, and that you have no place here? As
> in:
No. This is because people have a right to defend themselves like men,
something which boys will never learn.
>
> On Oct 22, 9:04=A0am,spinoza1111<spinoza1...@yahoo.com> wrote:
>
> > Personality based comments are childish and have no place here.
>
> --
> Tim
>
> "That excessive bail ought not to be required, nor excessive fines impose=
d,
> nor cruel and unusual punishments inflicted" =A0-- =A0Bill of Rights 1689=
- Hide quoted text -
>
> - Show quoted text -
|
|
0
|
|
|
|
Reply
|
spinoza1111 (3250)
|
10/22/2009 3:49:39 PM
|
|
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
> Keith Thompson <kst-u@mib.org> writes:
>> Corvus <noway@goaway.com> writes:
>>> I am looking for other ways to write the following in as few lines as
>>> possible, but I think I have hit the limit...
>>>
>>> x -= x/abs(x)
>>>
>>> So far, I have come up with this(it seems to work anyway):
>>>
>>> x -= x > 0 ? 1 : -1
>>
>> Note that these are not equivalent; when x == 0, the first invokes
>> undefined behavior, and the second sets x to 1.
>
> Also, the former is undefined if abs(x) can't be represented which is
> a practical concern on many machines when x == INT_MIN.
>
> <snip>
Good point. I knew there was *something* else that bothered me
about that, but I couldn't quite put my finger on it.
Another thing: The OP needs to decide exactly what he's trying to
accomplish. He's presented two expressions that aren't actually
equivalent, and asked for a way to do the same thing (which?) more
efficiently.
First, describe the problem correctly and unambiguously. Either
English, pseudoc-code, or straightforward C will do for this.
Second, implement it correctly (if you chose C for step 1, you're
done, but then you can't compare the code against the specification,
since they're the same). Nth, for some larger value of N, optimize
the code (N might well exceed the number of steps worth doing
at all). Xth, for some *very* large X, worry about expressing it
in a single expression. As I mentioned, step X can be necessary
if you're writing ia macro.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
|
|
0
|
|
|
|
Reply
|
kst-u (21469)
|
10/22/2009 3:55:52 PM
|
|
On Oct 22, 9:10=A0pm, gwowen <gwo...@gmail.com> wrote:
> On Oct 22, 1:36=A0pm, Richard Heathfield <r...@see.sig.invalid> wrote:
>
> > >> ( x > 0 )-( x < 0 )
>
> > It is a most readable expression, once you get used to the notion that
> > relational expressions have values in their own right. (It is not
> > unreasonable to assume a certain level of "literacy" in the reader
> > when assessing readability.)
>
> We must have wildly different ideas about readability. To me readable
> code is code that expresses intent clearly. "Programs are meant to be
> read by humans and only incidentally for computers to execute".
>
> x -=3D (x>0)-(x<0);
>
> does not express intent clearly. =A0One can work out what it does quite
> easily, but that's still work. It's all about "how" and not about
> "why".
>
> /* ... or a macro, obviously ... */
> static inline int signum (int x){
> =A0 return (x>0)-(x<0);}
>
> /* ... */
> x -=3D signum(x);
>
> is the best of both worlds.
Good, you're using my word. I like that, not because I'm vain
(although I am) but because somebody other than me has seen that the
OP is probably trying to implement signum, and signum is zero for
zero.
I also realize that I should have used inline int with a strongly
typed parameter as opposed to a macro.
Keep up the good work.
|
|
0
|
|
|
|
Reply
|
spinoza1111 (3250)
|
10/22/2009 3:56:28 PM
|
|
James Dow Allen <jdallen2000@yahoo.com> writes:
> On Oct 22, 1:51 pm, Keith Thompson <ks...@mib.org> wrote:
>> Rule of thumb: If a ?: operator can be written equivalently as an
>> if-else statement, write it as an if-else statement (unless it's
>> part of a macro definition).
>
> I think we'd all agree that "cutesy" shortcuts to achieve a
> false keystroke economy are wrong, but this statement goes much
> too far. It seems to assume that "if else" is more readable
> than "? :" but that should *not* be the case for a C programmer.
I was referring specifically to cases where a ?: operator appears at
the top level of a statement expression, and the second and third
operands' results are discarded. For example:
condition ? puts("A message") : puts("Another message");
In my opinion, using ?: here is just silly; it's better written as:
if (condition) {
puts("A message");
}
else {
puts("Another message");
}
or whatever brace style you prefer. In cases like this, the use of
the ?: operator tells me "I know what the ?: operator is, and you
should be impressed."
> I often string together ?, : and/or && and || into an involved
> expression, and add newlines and tabs to make it easy to read.
> IMHO the if/else equivalent would be harder to read because of
> all the "if/else" clutter.
Can you give an example? If it doesn't meet the criteria I mentioned
above, so that the transformation from ?: to if-else is absolutely
trivial, I probably wouldn't object. I don't find "if" and "else" to
be clutter; they're just part of the code.
(But tabs? Spaces only, please.)
> Surely none of us prefer Cobol's
> ADD OVERTIME TO SALARY
> or whatever it is, over C's
> salary += overtime;
> Not to extend the same courtesy to C's beautiful " ? : "
> would be to patronize the beginning C programmer.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
|
|
0
|
|
|
|
Reply
|
kst-u (21469)
|
10/22/2009 4:04:46 PM
|
|
spinoza1111 <spinoza1111@yahoo.com> writes:
> Good, you're using my word.
You invented the term signum? Cool.
Interestingly I learned it from John Nash while we were briefly
contestants on "Play Your Cards Right", in 1971. It was around this
time that I also invented cheez-whiz, price comparison websites and
the leg-before-wicket law.
|
|
0
|
|
|
|
Reply
|
gwowen (518)
|
10/22/2009 4:19:51 PM
|
|
In article <lny6n3tnxd.fsf@nuthaus.mib.org>,
Keith Thompson <kst-u@mib.org> wrote:
> James Dow Allen <jdallen2000@yahoo.com> writes:
> > On Oct 22, 1:51 pm, Keith Thompson <ks...@mib.org> wrote:
> >> Rule of thumb: If a ?: operator can be written equivalently as an
> >> if-else statement, write it as an if-else statement (unless it's
> >> part of a macro definition).
> >
> > I think we'd all agree that "cutesy" shortcuts to achieve a
> > false keystroke economy are wrong, but this statement goes much
> > too far. It seems to assume that "if else" is more readable
> > than "? :" but that should *not* be the case for a C programmer.
>
> I was referring specifically to cases where a ?: operator appears at
> the top level of a statement expression, and the second and third
> operands' results are discarded. For example:
>
> condition ? puts("A message") : puts("Another message");
>
> In my opinion, using ?: here is just silly; it's better written as:
>
> if (condition) {
> puts("A message");
> }
> else {
> puts("Another message");
> }
I don't think I agree with this. For such a simple case, something like:
puts condition ? "A message" : "Another message";
is much less clutter and more readable.
--
Tim
"That excessive bail ought not to be required, nor excessive fines imposed,
nor cruel and unusual punishments inflicted" -- Bill of Rights 1689
|
|
0
|
|
|
|
Reply
|
timstreater (943)
|
10/22/2009 4:34:35 PM
|
|
Keith Thompson <kst-u@mib.org> writes:
> Can you give an example? If it doesn't meet the criteria I mentioned
> above, so that the transformation from ?: to if-else is absolutely
> trivial, I probably wouldn't object. I don't find "if" and "else" to
> be clutter; they're just part of the code.
I'm not the original poster but this did remind me of something.
About 5 years ago there was a lengthy thread on c.l.c++ about whether
designing functions to be single-entry-single-exit was still a
worthwhile goal (since exceptions were necessarily a hidden other-exit
but I digress)...
Anyway, some of the strongest proponents of one-return-statement per
function would indulge this stylistic fetish by refactoring this:
/* ... excerpt from Game Of Life Code */
if(live_neighbours == 3) return true;
if(live_neighbours == 2) return data[x][y];
return false;
into
/* ... excerpt from Game Of Life Code */
return live_neighbours == 3 ? true
: live_neighbours == 2 ? data[x][y]
: false;
I don't like the latter because it requires me to either have the
precedence rules at my fingertips, or (more likely) LISP it up until
it said
return (live_neighbours == 3 ? true :
(live_neighbours == 2 ? data[x][y] : false));
|
|
0
|
|
|
|
Reply
|
gwowen (518)
|
10/22/2009 4:35:33 PM
|
|
Gareth Owen <gwowen@gmail.com> writes:
>You invented the term signum? Cool.
It is the latin word for �sign�.
�The symbol [a], to represent 0, 1, or -1, according to
whether a is 0, positive, or negative, was introduced by
Leopold Kronecker (1823-1891). He wrote:
Bezeichnet man naemlich mit [a] den
Werth Null oder +1 oder -1, je nachdem
die reelle Groesse a selbst gleich Null
oder positiv oder negativ ist ...
[February 14, 1878]�
http://www.luigigobbi.com/EarliestUsesOfSymbolsOfOperation/
>Interestingly I learned it from John Nash while we were
>briefly contestants on "Play Your Cards Right", in 1971. It
>was around this time that I also invented cheez-whiz, price
>comparison websites and the leg-before-wicket law.
From life one can learn that ideas are cheap.
The successful people are not the ones with ideas,
but the ones with the ability to turn ideas into
products and to do proper marketing for these product.
These people never or hardly ever use their time
to think about �optimizing an expression�, unless
they have indeed determined that the execution speed
of their product is a hindrance in marketing and
then used a profiler to determine that this expression
indeed is critical for performance.
That is, if we measure �success� by incoming money.
If we measure �success� by the pleasure gained by
optimizing an expression solely for the fun of doing
it, we get yet another story.
|
|
0
|
|
|
|
Reply
|
ram (2827)
|
10/22/2009 4:49:32 PM
|
|
In <PDYDm.351$5w5.236@text.news.virginmedia.com>, bartc wrote:
>
> "Richard Heathfield" <rjh@see.sig.invalid> wrote in message
> news:5Oqdnf0U3OL2zX3XnZ2dnUVZ8hydnZ2d@bt.com...
<snip>
>> The expression /is/ explicit.
>
> Not as explicit as, say:
>
> intsign(x)
Or indeed SIGN(x).
So
#define SIGN(x) (((x) > 0) - ((x) < 0))
and you're laughing.
<snip>
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
|
|
0
|
|
|
|
Reply
|
rjh (10789)
|
10/22/2009 6:01:15 PM
|
|
In <6e7b478f-4841-4929-9c2b-364cfa2c55b2@m3g2000pri.googlegroups.com>,
spinoza1111 wrote:
<snip>
> Nobody has yet conceded the main problem, that the OP is trying to
> implement signum and failing by giving a **wrong answer** when x is
> zero but the above solution seems to address this problem.
No. It doesn't "seem" anything. It addresses the problem.
> It's amazing that so few people here seem to know signum.
> Disturbing, as well.
It's amazing that you seem to think signum() is its only name. It's
been called many things in its time. SGN() is a common name, for
example.
<snip>
>> > I'm with Spinoza here
>>
>> That's not absolute proof that you're wrong, but it's not a hopeful
>> sign.
>
> Personality based comments are childish and have no place here.
It was a comment based on the observation that the majority of
articles posted under the account spinoza1111@yahoo.com contain
errors of one kind or another. I don't see what personalities have to
do with it. But if you want me to stop claiming that most of what you
write is wrong, start writing some right stuff. (Personally, I'm not
holding my breath waiting for that to happen. I've waited nearly a
decade and it hasn't happened yet to any noticeable degree.)
<usual nonsense about Fascism snipped>
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
|
|
0
|
|
|
|
Reply
|
rjh (10789)
|
10/22/2009 6:09:35 PM
|
|
Tim Streater <timstreater@waitrose.com> writes:
> In article <lny6n3tnxd.fsf@nuthaus.mib.org>,
> Keith Thompson <kst-u@mib.org> wrote:
[...]
>> I was referring specifically to cases where a ?: operator appears at
>> the top level of a statement expression, and the second and third
>> operands' results are discarded. For example:
>>
>> condition ? puts("A message") : puts("Another message");
>>
>> In my opinion, using ?: here is just silly; it's better written as:
>>
>> if (condition) {
>> puts("A message");
>> }
>> else {
>> puts("Another message");
>> }
>
> I don't think I agree with this. For such a simple case, something like:
>
> puts condition ? "A message" : "Another message";
>
> is much less clutter and more readable.
And a syntax error.
I think you mean:
puts(condition ? "A message" : "Another message");
I suppose there's some benefit in writing the function name only once.
Personally I still prefer the if-else form, but I see the point.
Ok, how about this:
if (x_has_been_set) {
printf("x = %d\n", x);
}
else {
puts("x has not been set");
}
I've seen people who would write that as:
x_has_been_set ? printf("x = %d\n", x) : puts("x has not been set");
which, IMHO, is absurd.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
|
|
0
|
|
|
|
Reply
|
kst-u (21469)
|
10/22/2009 6:10:36 PM
|
|
In <873a5bjsiy.fsf@linux-8rq8.site>, Gareth Owen wrote:
<snip>
> Anyway, some of the strongest proponents of one-return-statement per
> function would indulge this stylistic fetish
One man's stylistic fetish is another man's readability-friendly
constraint:
> by refactoring this:
>
> /* ... excerpt from Game Of Life Code */
> if(live_neighbours == 3) return true;
> if(live_neighbours == 2) return data[x][y];
> return false;
>
> into
>
> /* ... excerpt from Game Of Life Code */
> return live_neighbours == 3 ? true
> : live_neighbours == 2 ? data[x][y]
> : false;
>
> I don't like the latter
I don't like either of them. I like:
#include <stddef.h>
#include "board.h" /* header not included */
int board_cellstatus(board **b, size_t x, size_t y)
{
int newstatus = 0;
int live_neighbours = board_countneighbours(b, x, y);
if(live_neighbours == 3)
{
newstatus = 1;
}
else if(live_neighbours == 2)
{
newstatus = b->data[x][y];
}
return newstatus;
}
<snip>
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
|
|
0
|
|
|
|
Reply
|
rjh (10789)
|
10/22/2009 6:20:35 PM
|
|
Corvus wrote:
> I am looking for other ways to write the following in as few lines as
> possible, but I think I have hit the limit...
>
> x -= x/abs(x)
Uh...you've written it in one line. The only less would be zero lines...
|
|
0
|
|
|
|
Reply
|
markmcintyre2 (407)
|
10/22/2009 6:48:27 PM
|
|
In article <lnljj3ti3n.fsf@nuthaus.mib.org>,
Keith Thompson <kst-u@mib.org> wrote:
> Tim Streater <timstreater@waitrose.com> writes:
> > In article <lny6n3tnxd.fsf@nuthaus.mib.org>,
> > Keith Thompson <kst-u@mib.org> wrote:
> [...]
> >> I was referring specifically to cases where a ?: operator appears at
> >> the top level of a statement expression, and the second and third
> >> operands' results are discarded. For example:
> >>
> >> condition ? puts("A message") : puts("Another message");
> >>
> >> In my opinion, using ?: here is just silly; it's better written as:
> >>
> >> if (condition) {
> >> puts("A message");
> >> }
> >> else {
> >> puts("Another message");
> >> }
> >
> > I don't think I agree with this. For such a simple case, something like:
> >
> > puts condition ? "A message" : "Another message";
> >
> > is much less clutter and more readable.
>
> And a syntax error.
:-)
>
> I think you mean:
>
> puts(condition ? "A message" : "Another message");
Yes, very likely. I haven't written C for 20 years. I write PHP and
JavaScript these days, both of which include this construct.
> I suppose there's some benefit in writing the function name only once.
> Personally I still prefer the if-else form, but I see the point.
>
> Ok, how about this:
>
> if (x_has_been_set) {
> printf("x = %d\n", x);
> }
> else {
> puts("x has not been set");
> }
>
> I've seen people who would write that as:
>
> x_has_been_set ? printf("x = %d\n", x) : puts("x has not been set");
>
> which, IMHO, is absurd.
Well - there it is!
--
Tim
"That excessive bail ought not to be required, nor excessive fines imposed,
nor cruel and unusual punishments inflicted" -- Bill of Rights 1689
|
|
0
|
|
|
|
Reply
|
timstreater (943)
|
10/22/2009 7:06:14 PM
|
|
On Oct 22, 11:04=A0pm, Keith Thompson <ks...@mib.org> wrote:
> James Dow Allen <jdallen2...@yahoo.com> writes:
> > On Oct 22, 1:51=A0pm, Keith Thompson <ks...@mib.org> wrote:
> >> Rule of thumb: If a ?: operator can be written equivalently as an
> >> if-else statement, write it as an if-else statement (unless it's
> >> part of a macro definition).
> > ... this statement goes much
> > too far. =A0It seems to assume that "if else" is more readable
> > than "? :" but that should *not* be the case for a C programmer.
> I was referring specifically to cases where a ?: operator appears at
> the top level of a statement expression, ...
Sorry, I didn't mean to misconstrue what you were saying.
> Can you give an example?
OK, but let me confess that I really don't know what
is the *best* way to place white-space in code like this.
(And I normally don't scrunch "a < b" down to "a<b",
but isn't that a good way to make such code slightly
more readable?)
/* Return the median of 3 numbers */
int median3(int a, int b, int c)
{
return a<b ? b<c ? b
: a<c ? c : a
: c<b ? b
: c<a ? c : a;
}
This example may be too tame for much controversy.
I *would* post a more interesting example than this
one, but for that I'd want to be in a coffee-shop
with you all saying "Hello, James!" after I say,
"My name is James, and I write funny-looking C code."
James Dow Allen
|
|
0
|
|
|
|
Reply
|
jdallen2000 (489)
|
10/22/2009 7:24:20 PM
|
|
Richard Heathfield <rjh@see.sig.invalid> writes:
> In <873a5bjsiy.fsf@linux-8rq8.site>, Gareth Owen wrote:
>
> <snip>
>
>> Anyway, some of the strongest proponents of one-return-statement per
>> function would indulge this stylistic fetish
>
> One man's stylistic fetish is another man's readability-friendly
> constraint:
FWIW, I like SESE as a rule of thumb, especially if there's resource
management to do be done at function exit. Make refactoring much
easier.
int frobnicate()
{
int result;
/* allocate resources */
.
/* manipulate result*/
.
/* cleanup resources */
return result;
}
If the manipulations are even slightly complicated, that's the way.
But I can't bring myself to recommend:
int frobnicate(int val)
{
int result;
switch(val){
case 0: result = 7;
break;
case 1: result = 17;
break;
case 3: result = 173;
break;
default: result = -9;
}
return result;
}
over
int frobnicate(int val)
{
switch(val){
case 0: return 7;
case 1: return 17;
case 3: return 173;
default: return -9;
}
}
or even
int frobnicate(int val)
{
return val == 0 ? 7
: val == 1 ? 17
: val == 3 ? 173
: -9;
}
Due to the simplicity of the returned expressions, they all work
reasonably well for me. By and large, the people who wrote theose
incredibly stacked "return ?:?:?:" constructs really were fetishist
about SESE, and would tell you the middle option was an appalling
affront to good style.
FWIW, gcc 4.3.1, -O3 -S on i386-linux produces identical assembler for
the first two, and only-slightly-different (fractionally slower?!?)
for the third.
|
|
0
|
|
|
|
Reply
|
gwowen (518)
|
10/22/2009 7:42:41 PM
|
|
James Dow Allen <jdallen2000@yahoo.com> writes:
> /* Return the median of 3 numbers */
> int median3(int a, int b, int c)
> {
> return a<b ? b<c ? b
> : a<c ? c : a
> : c<b ? b
> : c<a ? c : a;
> }
I love ASCII art. What's it supposed to be? ;)
Rven with that relatively simple construct, I have to mentally insert
brackets before I convince myself its correct. If the expressions get
ever more complicated, I'm ever more glad that I don't have to
maintain that code.
int median3(int a, int b, int c)
{
if(a < b){
if(b < c) return b; /* a b c */
if(c < a) return a; /* c a b */
return c; /* a c b */
} else {
if(a < c) return a; /* b a c */
if(c < b) return b; /* c b a */
return c; /* b c a */
}
}
That, to me, is more clearly correct[0], at the cost of a lot more typing.
[0] which guarantees that I've cocked it up.
|
|
0
|
|
|
|
Reply
|
gwowen (518)
|
10/22/2009 7:58:05 PM
|
|
On Oct 22, 12:58=A0pm, Gareth Owen <gwo...@gmail.com> wrote:
> James Dow Allen <jdallen2...@yahoo.com> writes:
>
> > /* Return the median of 3 numbers */
> > int median3(int a, int b, int c)
> > {
> > =A0 =A0 =A0 return a<b ? b<c ? b
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 : a<c ? c : a
> > =A0 =A0 =A0 =A0 =A0 =A0: c<b ? b
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 : c<a ? c : a;
> > }
>
> I love ASCII art. =A0What's it supposed to be? ;)
>
> Rven with that relatively simple construct, I have to mentally insert
> brackets before I convince myself its correct. =A0If the expressions get
> ever more complicated, I'm ever more glad that I don't have to
> maintain that code.
>
> int median3(int a, int b, int c)
> {
> =A0 =A0if(a < b){
> =A0 =A0 =A0if(b < c) return b; =A0/* a b c */
> =A0 =A0 =A0if(c < a) return a; =A0/* c a b */
> =A0 =A0 =A0return c; =A0 =A0 =A0 =A0 =A0 =A0/* a c b */
> =A0 =A0} else {
> =A0 =A0 =A0if(a < c) return a; =A0/* b a c */
> =A0 =A0 =A0if(c < b) return b; =A0/* c b a */
> =A0 =A0 =A0return c; =A0 =A0 =A0 =A0 =A0 =A0/* b c a */
> =A0 =A0}
>
> }
>
> That, to me, is more clearly correct[0], at the cost of a lot more typing=
..
>
> [0] which guarantees that I've cocked it up.
I think that if you attach a unit test, then it is easy to be
confident about the alternate form:
typedef int e_type;
e_type median3(e_type a, e_type b, e_type c)
{
return (a < b) ? ((b < c) ? b : ((a < c) ? c : a)) : ((a < c) ?
a : ((b < c) ? c : b));
}
#ifdef UNIT_TEST
int main(void)
{
e_type i,
j,
k,
m;
for (i =3D 0; i < 3; i++)
for (j =3D 0; j < 3; j++)
for (k =3D 0; k < 3; k++) {
m =3D median3(i, j, k);
printf("median of %d %d %d is %d\n", i, j, k, m);
}
return 0;
}
#endif
/*
median of 0 0 0 is 0
median of 0 0 1 is 0
median of 0 0 2 is 0
median of 0 1 0 is 0
median of 0 1 1 is 1
median of 0 1 2 is 1
median of 0 2 0 is 0
median of 0 2 1 is 1
median of 0 2 2 is 2
median of 1 0 0 is 0
median of 1 0 1 is 1
median of 1 0 2 is 1
median of 1 1 0 is 1
median of 1 1 1 is 1
median of 1 1 2 is 1
median of 1 2 0 is 1
median of 1 2 1 is 1
median of 1 2 2 is 2
median of 2 0 0 is 0
median of 2 0 1 is 1
median of 2 0 2 is 2
median of 2 1 0 is 1
median of 2 1 1 is 1
median of 2 1 2 is 2
median of 2 2 0 is 2
median of 2 2 1 is 2
median of 2 2 2 is 2
*/
|
|
0
|
|
|
|
Reply
|
dcorbit (2696)
|
10/22/2009 8:39:55 PM
|
|
On Oct 22, 1:39=A0pm, user923005 <dcor...@connx.com> wrote:
> On Oct 22, 12:58=A0pm, Gareth Owen <gwo...@gmail.com> wrote:
>
>
>
>
>
> > James Dow Allen <jdallen2...@yahoo.com> writes:
>
> > > /* Return the median of 3 numbers */
> > > int median3(int a, int b, int c)
> > > {
> > > =A0 =A0 =A0 return a<b ? b<c ? b
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 : a<c ? c : a
> > > =A0 =A0 =A0 =A0 =A0 =A0: c<b ? b
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 : c<a ? c : a;
> > > }
>
> > I love ASCII art. =A0What's it supposed to be? ;)
>
> > Rven with that relatively simple construct, I have to mentally insert
> > brackets before I convince myself its correct. =A0If the expressions ge=
t
> > ever more complicated, I'm ever more glad that I don't have to
> > maintain that code.
>
> > int median3(int a, int b, int c)
> > {
> > =A0 =A0if(a < b){
> > =A0 =A0 =A0if(b < c) return b; =A0/* a b c */
> > =A0 =A0 =A0if(c < a) return a; =A0/* c a b */
> > =A0 =A0 =A0return c; =A0 =A0 =A0 =A0 =A0 =A0/* a c b */
> > =A0 =A0} else {
> > =A0 =A0 =A0if(a < c) return a; =A0/* b a c */
> > =A0 =A0 =A0if(c < b) return b; =A0/* c b a */
> > =A0 =A0 =A0return c; =A0 =A0 =A0 =A0 =A0 =A0/* b c a */
> > =A0 =A0}
>
> > }
>
> > That, to me, is more clearly correct[0], at the cost of a lot more typi=
ng.
>
> > [0] which guarantees that I've cocked it up.
>
> I think that if you attach a unit test, then it is easy to be
> confident about the alternate form:
>
> typedef int =A0 =A0 e_type;
>
> e_type =A0 =A0 =A0 =A0 =A0median3(e_type a, e_type b, e_type c)
> {
> =A0 =A0 return (a < b) ? ((b < c) ? b : ((a < c) ? c : a)) : ((a < c) ?
> a : ((b < c) ? c : b));
>
> }
>
> #ifdef UNIT_TEST
>
> int =A0 =A0 =A0 =A0 =A0 =A0 main(void)
> {
> =A0 =A0 e_type =A0 =A0 =A0 =A0 =A0i,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 j,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 k,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 m;
> =A0 =A0 for (i =3D 0; i < 3; i++)
> =A0 =A0 =A0 =A0 for (j =3D 0; j < 3; j++)
> =A0 =A0 =A0 =A0 =A0 =A0 for (k =3D 0; k < 3; k++) {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 m =3D median3(i, j, k);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 printf("median of %d %d %d is %d\n", i, j=
, k, m);
> =A0 =A0 =A0 =A0 =A0 =A0 }
> =A0 =A0 return 0;
>
> }
>
> #endif
> /*
> median of 0 0 0 is 0
> median of 0 0 1 is 0
> median of 0 0 2 is 0
> median of 0 1 0 is 0
> median of 0 1 1 is 1
> median of 0 1 2 is 1
> median of 0 2 0 is 0
> median of 0 2 1 is 1
> median of 0 2 2 is 2
> median of 1 0 0 is 0
> median of 1 0 1 is 1
> median of 1 0 2 is 1
> median of 1 1 0 is 1
> median of 1 1 1 is 1
> median of 1 1 2 is 1
> median of 1 2 0 is 1
> median of 1 2 1 is 1
> median of 1 2 2 is 2
> median of 2 0 0 is 0
> median of 2 0 1 is 1
> median of 2 0 2 is 2
> median of 2 1 0 is 1
> median of 2 1 1 is 1
> median of 2 1 2 is 2
> median of 2 2 0 is 2
> median of 2 2 1 is 2
> median of 2 2 2 is 2
> */
Showing both methods:
typedef int e_type;
e_type median3(e_type a, e_type b, e_type c)
{
return (a < b) ? ((b < c) ? b : ((a < c) ? c : a)) : ((a < c) ?
a : ((b < c) ? c : b));
}
int median3a(int a, int b, int c)
{
if (a < b) {
if (b < c)
return b; /* a b c */
if (c < a)
return a; /* c a b */
return c; /* a c b */
} else {
if (a < c)
return a; /* b a c */
if (c < b)
return b; /* c b a */
return c; /* b c a */
}
}
#ifdef UNIT_TEST
int main(void)
{
e_type i,
j,
k,
m,
m2;
for (i =3D 0; i < 3; i++)
for (j =3D 0; j < 3; j++)
for (k =3D 0; k < 3; k++) {
m =3D median3(i, j, k);
printf("median of %d %d %d is %d\n", i, j, k, m);
m2 =3D median3a(i, j, k);
printf("median of %d %d %d is %d\n", i, j, k, m2);
if (m2 !=3D m)
printf("Disagreement of %d verses %d\n", m2, m);
}
return 0;
}
#endif
/*
median of 0 0 0 is 0
median of 0 0 0 is 0
median of 0 0 1 is 0
median of 0 0 1 is 0
median of 0 0 2 is 0
median of 0 0 2 is 0
median of 0 1 0 is 0
median of 0 1 0 is 0
median of 0 1 1 is 1
median of 0 1 1 is 1
median of 0 1 2 is 1
median of 0 1 2 is 1
median of 0 2 0 is 0
median of 0 2 0 is 0
median of 0 2 1 is 1
median of 0 2 1 is 1
median of 0 2 2 is 2
median of 0 2 2 is 2
median of 1 0 0 is 0
median of 1 0 0 is 0
median of 1 0 1 is 1
median of 1 0 1 is 1
median of 1 0 2 is 1
median of 1 0 2 is 1
median of 1 1 0 is 1
median of 1 1 0 is 1
median of 1 1 1 is 1
median of 1 1 1 is 1
median of 1 1 2 is 1
median of 1 1 2 is 1
median of 1 2 0 is 1
median of 1 2 0 is 1
median of 1 2 1 is 1
median of 1 2 1 is 1
median of 1 2 2 is 2
median of 1 2 2 is 2
median of 2 0 0 is 0
median of 2 0 0 is 0
median of 2 0 1 is 1
median of 2 0 1 is 1
median of 2 0 2 is 2
median of 2 0 2 is 2
median of 2 1 0 is 1
median of 2 1 0 is 1
median of 2 1 1 is 1
median of 2 1 1 is 1
median of 2 1 2 is 2
median of 2 1 2 is 2
median of 2 2 0 is 2
median of 2 2 0 is 2
median of 2 2 1 is 2
median of 2 2 1 is 2
median of 2 2 2 is 2
median of 2 2 2 is 2
*/
|
|
0
|
|
|
|
Reply
|
dcorbit (2696)
|
10/22/2009 8:43:18 PM
|
|
In article <87ws2ndxla.fsf@linux-8rq8.site>,
Gareth Owen <gwowen@gmail.com> wrote:
[snip]
> FWIW, I like SESE as a rule of thumb, especially if there's resource
> management to do be done at function exit. Make refactoring much
> easier.
>
> int frobnicate()
> {
> int result;
> /* allocate resources */
> .
> /* manipulate result*/
> .
> /* cleanup resources */
> return result;
> }
The C I wrote typically involved a lot of syntax checking of some input
string with a lot of early returns on error. The preceded any attempt to
allocate resources.
> If the manipulations are even slightly complicated, that's the way.
>
> But I can't bring myself to recommend:
>
> int frobnicate(int val)
> {
> int result;
> switch(val){
> case 0: result = 7;
> break;
> case 1: result = 17;
> break;
> case 3: result = 173;
> break;
> default: result = -9;
> }
> return result;
> }
>
> over
>
> int frobnicate(int val)
> {
> switch(val){
> case 0: return 7;
> case 1: return 17;
> case 3: return 173;
> default: return -9;
> }
> }
>
> or even
>
> int frobnicate(int val)
> {
> return val == 0 ? 7
> : val == 1 ? 17
> : val == 3 ? 173
> : -9;
> }
>
> Due to the simplicity of the returned expressions, they all work
> reasonably well for me. By and large, the people who wrote theose
> incredibly stacked "return ?:?:?:" constructs really were fetishist
> about SESE, and would tell you the middle option was an appalling
> affront to good style.
Well, rude anglo-saxon gestures to them, in that case.
--
Tim
"That excessive bail ought not to be required, nor excessive fines imposed,
nor cruel and unusual punishments inflicted" -- Bill of Rights 1689
|
|
0
|
|
|
|
Reply
|
timstreater (943)
|
10/22/2009 8:59:36 PM
|
|
James Dow Allen <jdallen2000@yahoo.com> writes:
> On Oct 22, 11:04 pm, Keith Thompson <ks...@mib.org> wrote:
>> James Dow Allen <jdallen2...@yahoo.com> writes:
>> > On Oct 22, 1:51 pm, Keith Thompson <ks...@mib.org> wrote:
>> >> Rule of thumb: If a ?: operator can be written equivalently as an
>> >> if-else statement, write it as an if-else statement (unless it's
>> >> part of a macro definition).
>> > ... this statement goes much
>> > too far. It seems to assume that "if else" is more readable
>> > than "? :" but that should *not* be the case for a C programmer.
>> I was referring specifically to cases where a ?: operator appears at
>> the top level of a statement expression, ...
>
> Sorry, I didn't mean to misconstrue what you were saying.
>
>> Can you give an example?
>
> OK, but let me confess that I really don't know what
> is the *best* way to place white-space in code like this.
> (And I normally don't scrunch "a < b" down to "a<b",
> but isn't that a good way to make such code slightly
> more readable?)
>
> /* Return the median of 3 numbers */
> int median3(int a, int b, int c)
> {
> return a<b ? b<c ? b
> : a<c ? c : a
> : c<b ? b
> : c<a ? c : a;
> }
I'm sure that will look very simple after a few hours of study.
I do sometimes write fairly long *linear* chains of conditional
operators. For example:
printf("x = %d = %s\n",
x,
x == SOME_CONSTANT ? "SOME_CONSTANT" :
x == ANOTHER_CONSTANT ? "ANOTHER_CONSTANT" :
x == YET_ANOTHER_CONSTANT ? "YET_ANOTHER_CONSTANT" :
/* ... */
"???");
(Calling a function that uses a switch statement to return the
value of one of several string literals might make more sense;
I probably had some obscure reason not to do that.)
It might seem like the long chain needs some parentheses, but it
really doesn't, for much the same reason that you can write:
if (foo) {
...
}
else if (bar) {
...
}
else if (baz) {
...
}
else {
...
}
and it's actually clearer than:
if (foo) {
...
}
else {
if (bar) {
...
}
else {
if (baz) {
...
}
else {
...
}
}
}
(<OT>Some languages have an additional "elseif", "elsif", or "elif"
keyword for just this reason.</OT>).
> This example may be too tame for much controversy.
> I *would* post a more interesting example than this
> one, but for that I'd want to be in a coffee-shop
> with you all saying "Hello, James!" after I say,
> "My name is James, and I write funny-looking C code."
8-)}
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
|
|
0
|
|
|
|
Reply
|
kst-u (21469)
|
10/22/2009 9:14:49 PM
|
|
On Thu, 22 Oct 2009 12:24:20 -0700, James Dow Allen wrote:
> On Oct 22, 11:04 pm, Keith Thompson <ks...@mib.org> wrote:
>> James Dow Allen <jdallen2...@yahoo.com> writes:
>> > On Oct 22, 1:51 pm, Keith Thompson <ks...@mib.org> wrote:
Here is mine:
***/
#include <stdio.h>
int median3(int a,int b,int c);
int main(void)
{
int a,b,c,m;
for( a=0; a< 3; a++)
for( b=0; b< 3; b++)
for( c=0; c< 3; c++) {
m = median3(a,b,c);
printf("%d %d %d median3=%d\n" , a,b,c,m);
}
return 0;
}
int median3(int a,int b,int c)
{
switch ((a>b)+((b>c)<<1)+((c>a)<<2)) {
case 0: return a;
case 1: return c;
case 2: return a;
case 3: return b;
case 4: return b;
case 5: return a;
case 6: return c;
}
}
/****
:-)
AvK
|
|
0
|
|
|
|
Reply
|
root32 (398)
|
10/22/2009 9:24:13 PM
|
|
On Oct 22, 2:24=A0pm, Moi <r...@invalid.address.org> wrote:
> On Thu, 22 Oct 2009 12:24:20 -0700, James Dow Allen wrote:
> > On Oct 22, 11:04=A0pm, Keith Thompson <ks...@mib.org> wrote:
> >> James Dow Allen <jdallen2...@yahoo.com> writes:
> >> > On Oct 22, 1:51=A0pm, Keith Thompson <ks...@mib.org> wrote:
>
> Here is mine:
> ***/
>
> #include <stdio.h>
>
> int median3(int a,int b,int c);
> int main(void)
> {
> int a,b,c,m;
>
> for( a=3D0; a< 3; a++)
> =A0 =A0 =A0 =A0 for( b=3D0; b< 3; b++)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 for( c=3D0; c< 3; c++) =A0{
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 m =3D median3(a,b,c);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 printf("%d %d %d median3=3D%d\n" , a,b,c,=
m);
> =A0 =A0 =A0 =A0 }
> return 0;
>
> }
>
> int median3(int a,int b,int c)
> {
> switch ((a>b)+((b>c)<<1)+((c>a)<<2)) {
> case 0: return a;
> case 1: return c;
> case 2: return a;
> case 3: return b;
> case 4: return b;
> case 5: return a;
> case 6: return c;
> =A0 =A0 =A0 =A0 }
>
> }
>
> /****
>
> :-)
> AvK
/*
Surprising to me, the switch ran 4x slower than the simple if() tests.
It appears that the missed branch predictions are killer.
I guess that profile guided optimization will help your routine
quite a bit if the data has some particular pattern.
*/
typedef int e_type;
e_type median3(e_type a, e_type b, e_type c)
{
return (a < b) ? ((b < c) ? b : ((a < c) ? c : a)) : ((a < c) ?
a : ((b < c) ? c : b));
}
e_type median3a(e_type a, e_type b, e_type c)
{
if (a < b) {
if (b < c)
return b; /* a b c */
if (c < a)
return a; /* c a b */
return c; /* a c b */
} else {
if (a < c)
return a; /* b a c */
if (c < b)
return b; /* c b a */
return c; /* b c a */
}
}
e_type median3b(e_type a, e_type b, e_type c)
{
switch ((a > b) + ((b > c) << 1) + ((c > a) << 2)) {
case 0:
return a;
case 1:
return c;
case 2:
return a;
case 3:
return b;
case 4:
return b;
case 5:
return a;
case 6:
default:
return c;
}
}
#ifdef UNIT_TEST
#include <stdio.h>
int main(void)
{
e_type i,
j,
k,
m,
m2,
m3;
for (i =3D 0; i < 3000; i++)
for (j =3D 0; j < 3000; j++)
for (k =3D 0; k < 3000; k++) {
m =3D median3(i, j, k);
m2 =3D median3a(i, j, k);
m3 =3D median3b(i, j, k);
#ifdef SHOW_RESULTS
printf("median of %d %d %d is %d\n", i, j, k, m3);
#endif
if (m3 !=3D m)
printf("Disagreement of %d verses %d\n", m3, m);
if (m2 !=3D m)
printf("Disagreement of %d verses %d\n", m2, m);
}
return 0;
}
#endif
/*
Profile results were:
Function Name,Exclusive Samples,Exclusive Samples %,
"median3b","48,756",55.35,
"main","16,790",19.06,
"median3a","11,644",13.22,
"median3","10,898",12.37,
*/
|
|
0
|
|
|
|
Reply
|
dcorbit (2696)
|
10/22/2009 10:07:58 PM
|
|
On Thu, 22 Oct 2009 15:07:58 -0700, user923005 wrote:
> On Oct 22, 2:24 pm, Moi <r...@invalid.address.org> wrote:
>> int median3(int a,int b,int c)
>> {
>> switch ((a>b)+((b>c)<<1)+((c>a)<<2)) { case 0: return a;
>> case 1: return c;
>> case 2: return a;
>> case 3: return b;
>> case 4: return b;
>> case 5: return a;
>> case 6: return c;
>> }
>>
>> }
>>
>
>
> Surprising to me, the switch ran 4x slower than the simple if() tests.
>
> It appears that the missed branch predictions are killer. I guess that
> profile guided optimization will help your routine quite a bit if the
> data has some particular pattern. */
Thanks for benchmarking. It was not intended to be a racer...
There are probably too many sequence points and too few common
subexpressions to give the compiler enough freedom to optimise.
There are other cases where this "computed enumeration" method can save
you some headaches. (e.g. 2D range-compare) It is relatively easy to
build and test, even if the conditions get very complex. The cases where
you know beforehand that you won't get it right the first time.
AvK
|
|
0
|
|
|
|
Reply
|
root32 (398)
|
10/22/2009 10:42:20 PM
|
|
On Oct 22, 3:42=A0pm, Moi <r...@invalid.address.org> wrote:
> On Thu, 22 Oct 2009 15:07:58 -0700, user923005 wrote:
> > On Oct 22, 2:24=A0pm, Moi <r...@invalid.address.org> wrote:
> >> int median3(int a,int b,int c)
> >> {
> >> switch ((a>b)+((b>c)<<1)+((c>a)<<2)) { case 0: return a;
> >> case 1: return c;
> >> case 2: return a;
> >> case 3: return b;
> >> case 4: return b;
> >> case 5: return a;
> >> case 6: return c;
> >> =A0 =A0 =A0 =A0 }
>
> >> }
>
> > Surprising to me, the switch ran 4x slower than the simple if() tests.
>
> > It appears that the missed branch predictions are killer. I guess that
> > profile guided optimization will help your routine quite a bit if the
> > data has some particular pattern. */
>
> Thanks for benchmarking. It was not intended to be a racer...
> There are probably too many sequence points and too few common
> subexpressions to give the compiler enough freedom to optimise.
>
> There are other cases where this "computed enumeration" method can save
> you some headaches. (e.g. 2D range-compare) It is relatively easy to
> build and test, even if the conditions get very complex. The cases where
> you know beforehand that you won't get it right the first time.
Gave me an idea:
int median3c(int a, int b, int c)
{
e_type elist[7] =3D {a,c,a,b,b,a,c};
return elist[(a > b) + ((b > c) << 1) + ((c > a) << 2)];
}
I am benching it now.
I guess that the 7 assignments filling the array will be expensive but
a benchmark may prove revealing.
|
|
0
|
|
|
|
Reply
|
dcorbit (2696)
|
10/23/2009 12:10:37 AM
|
|
On Oct 22, 5:10=A0pm, user923005 <dcor...@connx.com> wrote:
> On Oct 22, 3:42=A0pm, Moi <r...@invalid.address.org> wrote:
>
>
>
>
>
> > On Thu, 22 Oct 2009 15:07:58 -0700, user923005 wrote:
> > > On Oct 22, 2:24=A0pm, Moi <r...@invalid.address.org> wrote:
> > >> int median3(int a,int b,int c)
> > >> {
> > >> switch ((a>b)+((b>c)<<1)+((c>a)<<2)) { case 0: return a;
> > >> case 1: return c;
> > >> case 2: return a;
> > >> case 3: return b;
> > >> case 4: return b;
> > >> case 5: return a;
> > >> case 6: return c;
> > >> =A0 =A0 =A0 =A0 }
>
> > >> }
>
> > > Surprising to me, the switch ran 4x slower than the simple if() tests=
..
>
> > > It appears that the missed branch predictions are killer. I guess tha=
t
> > > profile guided optimization will help your routine quite a bit if the
> > > data has some particular pattern. */
>
> > Thanks for benchmarking. It was not intended to be a racer...
> > There are probably too many sequence points and too few common
> > subexpressions to give the compiler enough freedom to optimise.
>
> > There are other cases where this "computed enumeration" method can save
> > you some headaches. (e.g. 2D range-compare) It is relatively easy to
> > build and test, even if the conditions get very complex. The cases wher=
e
> > you know beforehand that you won't get it right the first time.
>
> Gave me an idea:
> int =A0 =A0 =A0 =A0 =A0 =A0 median3c(int a, int b, int c)
> {
> =A0 =A0 =A0 =A0 =A0 e_type elist[7] =3D {a,c,a,b,b,a,c};
> =A0 =A0 =A0 =A0 =A0 return elist[(a > b) + ((b > c) << 1) + ((c > a) << 2=
)];
>
> }
>
> I am benching it now.
>
> I guess that the 7 assignments filling the array will be expensive but
> a benchmark may prove revealing.
The array idea was worse.
typedef int e_type;
e_type median3(e_type a, e_type b, e_type c)
{
return (a < b) ? ((b < c) ? b : ((a < c) ? c : a)) : ((a < c) ?
a : ((b < c) ? c : b));
}
e_type median3a(e_type a, e_type b, e_type c)
{
if (a < b) {
if (b < c)
return b; /* a b c */
if (c < a)
return a; /* c a b */
return c; /* a c b */
} else {
if (a < c)
return a; /* b a c */
if (c < b)
return b; /* c b a */
return c; /* b c a */
}
}
e_type median3b(e_type a, e_type b, e_type c)
{
switch ((a > b) + ((b > c) << 1) + ((c > a) << 2)) {
case 0:
return a;
case 1:
return c;
case 2:
return a;
case 3:
return b;
case 4:
return b;
case 5:
return a;
case 6:
default:
return c;
}
}
int median3c(int a, int b, int c)
{
e_type elist[7] =3D {a, c, a, b, b, a, c};
return elist[(a > b) + ((b > c) << 1) + ((c > a) << 2)];
}
#ifdef UNIT_TEST
#include <stdio.h>
int main(void)
{
e_type i,
j,
k,
m,
m2,
m3,
m4;
for (i =3D 0; i < 3000; i++)
for (j =3D 0; j < 3000; j++)
for (k =3D 0; k < 3000; k++) {
m =3D median3(i, j, k);
m2 =3D median3a(i, j, k);
m3 =3D median3b(i, j, k);
m4 =3D median3c(i, j, k);
#ifdef SHOW_RESULTS
printf("median of %d %d %d is %d\n", i, j, k, m3);
#endif
if (m4 !=3D m)
printf("Disagreement (4) of %d verses %d\n", m3,
m);
if (m3 !=3D m)
printf("Disagreement (3) of %d verses %d\n", m3,
m);
if (m2 !=3D m)
printf("Disagreement (2) of %d verses %d\n", m2,
m);
}
return 0;
}
#endif
/*
Profile results were:
Function Name,Exclusive Samples,Exclusive Samples %,
"median3c","51,810",38.73,
"median3b","36,892",27.58,
"main","22,829",17.07,
"median3a","11,904",8.90,
"median3","10,320",7.72,
*/
|
|
0
|
|
|
|
Reply
|
dcorbit (2696)
|
10/23/2009 12:19:13 AM
|
|
On Oct 22, 5:10=A0pm, user923005 <dcor...@connx.com> wrote:
> On Oct 22, 3:42=A0pm, Moi <r...@invalid.address.org> wrote:
>
>
>
>
>
> > On Thu, 22 Oct 2009 15:07:58 -0700, user923005 wrote:
> > > On Oct 22, 2:24=A0pm, Moi <r...@invalid.address.org> wrote:
> > >> int median3(int a,int b,int c)
> > >> {
> > >> switch ((a>b)+((b>c)<<1)+((c>a)<<2)) { case 0: return a;
> > >> case 1: return c;
> > >> case 2: return a;
> > >> case 3: return b;
> > >> case 4: return b;
> > >> case 5: return a;
> > >> case 6: return c;
> > >> =A0 =A0 =A0 =A0 }
>
> > >> }
>
> > > Surprising to me, the switch ran 4x slower than the simple if() tests=
..
>
> > > It appears that the missed branch predictions are killer. I guess tha=
t
> > > profile guided optimization will help your routine quite a bit if the
> > > data has some particular pattern. */
>
> > Thanks for benchmarking. It was not intended to be a racer...
> > There are probably too many sequence points and too few common
> > subexpressions to give the compiler enough freedom to optimise.
>
> > There are other cases where this "computed enumeration" method can save
> > you some headaches. (e.g. 2D range-compare) It is relatively easy to
> > build and test, even if the conditions get very complex. The cases wher=
e
> > you know beforehand that you won't get it right the first time.
>
> Gave me an idea:
> int =A0 =A0 =A0 =A0 =A0 =A0 median3c(int a, int b, int c)
> {
> =A0 =A0 =A0 =A0 =A0 e_type elist[7] =3D {a,c,a,b,b,a,c};
> =A0 =A0 =A0 =A0 =A0 return elist[(a > b) + ((b > c) << 1) + ((c > a) << 2=
)];
>
> }
>
> I am benching it now.
>
> I guess that the 7 assignments filling the array will be expensive but
> a benchmark may prove revealing.
Got another idea worth trying:
e_type median3d(e_type a, e_type b, e_type c)
{
e_type *pa =3D &a;
e_type *pb =3D &b;
e_type *pc =3D &c;
const e_type *elist[7] =3D {pa, pc, pa, pb, pb, pa, pc};
return *elist[(a > b) + ((b > c) << 1) + ((c > a) << 2)];
}
I am benchmarking now.
|
|
0
|
|
|
|
Reply
|
dcorbit (2696)
|
10/23/2009 12:24:00 AM
|
|
On Oct 22, 5:24=A0pm, user923005 <dcor...@connx.com> wrote:
> On Oct 22, 5:10=A0pm, user923005 <dcor...@connx.com> wrote:
>
>
>
>
>
> > On Oct 22, 3:42=A0pm, Moi <r...@invalid.address.org> wrote:
>
> > > On Thu, 22 Oct 2009 15:07:58 -0700, user923005 wrote:
> > > > On Oct 22, 2:24=A0pm, Moi <r...@invalid.address.org> wrote:
> > > >> int median3(int a,int b,int c)
> > > >> {
> > > >> switch ((a>b)+((b>c)<<1)+((c>a)<<2)) { case 0: return a;
> > > >> case 1: return c;
> > > >> case 2: return a;
> > > >> case 3: return b;
> > > >> case 4: return b;
> > > >> case 5: return a;
> > > >> case 6: return c;
> > > >> =A0 =A0 =A0 =A0 }
>
> > > >> }
>
> > > > Surprising to me, the switch ran 4x slower than the simple if() tes=
ts.
>
> > > > It appears that the missed branch predictions are killer. I guess t=
hat
> > > > profile guided optimization will help your routine quite a bit if t=
he
> > > > data has some particular pattern. */
>
> > > Thanks for benchmarking. It was not intended to be a racer...
> > > There are probably too many sequence points and too few common
> > > subexpressions to give the compiler enough freedom to optimise.
>
> > > There are other cases where this "computed enumeration" method can sa=
ve
> > > you some headaches. (e.g. 2D range-compare) It is relatively easy to
> > > build and test, even if the conditions get very complex. The cases wh=
ere
> > > you know beforehand that you won't get it right the first time.
>
> > Gave me an idea:
> > int =A0 =A0 =A0 =A0 =A0 =A0 median3c(int a, int b, int c)
> > {
> > =A0 =A0 =A0 =A0 =A0 e_type elist[7] =3D {a,c,a,b,b,a,c};
> > =A0 =A0 =A0 =A0 =A0 return elist[(a > b) + ((b > c) << 1) + ((c > a) <<=
2)];
>
> > }
>
> > I am benching it now.
>
> > I guess that the 7 assignments filling the array will be expensive but
> > a benchmark may prove revealing.
>
> Got another idea worth trying:
> e_type =A0 =A0 =A0 =A0 =A0median3d(e_type a, e_type b, e_type c)
> {
> =A0 =A0 e_type =A0 =A0 =A0 =A0 *pa =3D &a;
> =A0 =A0 e_type =A0 =A0 =A0 =A0 *pb =3D &b;
> =A0 =A0 e_type =A0 =A0 =A0 =A0 *pc =3D &c;
> =A0 =A0 const e_type =A0 *elist[7] =3D {pa, pc, pa, pb, pb, pa, pc};
> =A0 =A0 return *elist[(a > b) + ((b > c) << 1) + ((c > a) << 2)];
>
> }
>
> I am benchmarking now.
/*
Using pointers offers no improvement.
*/
typedef int e_type;
e_type median3(e_type a, e_type b, e_type c)
{
return (a < b) ? ((b < c) ? b : ((a < c) ? c : a)) : ((a < c) ?
a : ((b < c) ? c : b));
}
e_type median3a(e_type a, e_type b, e_type c)
{
if (a < b) {
if (b < c)
return b; /* a b c */
if (c < a)
return a; /* c a b */
return c; /* a c b */
} else {
if (a < c)
return a; /* b a c */
if (c < b)
return b; /* c b a */
return c; /* b c a */
}
}
e_type median3b(e_type a, e_type b, e_type c)
{
switch ((a > b) + ((b > c) << 1) + ((c > a) << 2)) {
case 0:
return a;
case 1:
return c;
case 2:
return a;
case 3:
return b;
case 4:
return b;
case 5:
return a;
case 6:
default:
return c;
}
}
e_type median3c(e_type a, e_type b, e_type c)
{
e_type elist[7] =3D {a, c, a, b, b, a, c};
return elist[(a > b) + ((b > c) << 1) + ((c > a) << 2)];
}
e_type median3d(e_type a, e_type b, e_type c)
{
e_type *pa =3D &a;
e_type *pb =3D &b;
e_type *pc =3D &c;
const e_type *elist[7] =3D {pa, pc, pa, pb, pb, pa, pc};
return *elist[(a > b) + ((b > c) << 1) + ((c > a) << 2)];
}
#ifdef UNIT_TEST
#include <stdio.h>
int main(void)
{
e_type i,
j,
k,
m,
m2,
m3,
m4,
m5;
for (i =3D 0; i < 3000; i++)
for (j =3D 0; j < 3000; j++)
for (k =3D 0; k < 3000; k++) {
m =3D median3(i, j, k);
m2 =3D median3a(i, j, k);
m3 =3D median3b(i, j, k);
m4 =3D median3c(i, j, k);
m5 =3D median3d(i, j, k);
#ifdef SHOW_RESULTS
printf("median of %d %d %d is %d\n", i, j, k, m3);
#endif
if (m5 !=3D m)
printf("Disagreement (5) of %d verses %d\n", m5,
m);
if (m4 !=3D m)
printf("Disagreement (4) of %d verses %d\n", m4,
m);
if (m3 !=3D m)
printf("Disagreement (3) of %d verses %d\n", m3,
m);
if (m2 !=3D m)
printf("Disagreement (2) of %d verses %d\n", m2,
m);
}
return 0;
}
#endif
/*
Profile results were:
Function Name,Exclusive Samples,Exclusive Samples %,
"median3d","48,112",25.95,
"median3c","47,707",25.73,
"median3b","40,897",22.06,
"main","27,725",14.95,
"median3a","10,774",5.81,
"median3","10,196",5.50,
*/
|
|
0
|
|
|
|
Reply
|
dcorbit (2696)
|
10/23/2009 12:40:47 AM
|
|
On Oct 23, 12:19=A0am, Gareth Owen <gwo...@gmail.com> wrote:
> spinoza1111<spinoza1...@yahoo.com> writes:
> > Good, you're using my word.
>
> You invented the term signum? =A0Cool.
>
> Interestingly I learned it from John Nash while we were briefly
> contestants on "Play Your Cards Right", in 1971. =A0It was around this
> time that I also invented cheez-whiz, price comparison websites and
> the leg-before-wicket law.
What are you, 14 years old? Crack a book.
http://en.wikipedia.org/wiki/Sign_function
|
|
0
|
|
|
|
Reply
|
spinoza1111 (3250)
|
10/23/2009 12:41:59 AM
|
|
On Oct 23, 2:09=A0am, Richard Heathfield <r...@see.sig.invalid> wrote:
> In <6e7b478f-4841-4929-9c2b-364cfa2c5...@m3g2000pri.googlegroups.com>,
>
> spinoza1111wrote:
>
> <snip>
>
> > Nobody has yet conceded the main problem, that the OP is trying to
> > implement signum and failing by giving a **wrong answer** when x is
> > zero but the above solution seems to address this problem.
>
> No. It doesn't "seem" anything. It addresses the problem.
>
> > It's amazing that so few people here seem to know signum.
> > Disturbing, as well.
>
> It's amazing that you seem to think signum() is its only name. It's
> been called many things in its time. SGN() is a common name, for
> example.
>
> <snip>
>
> >> > I'm with Spinoza here
>
> >> That's not absolute proof that you're wrong, but it's not a hopeful
> >> sign.
>
> > Personality based comments are childish and have no place here.
>
> It was a comment based on the observation that the majority of
> articles posted under the account spinoza1...@yahoo.com contain
> errors of one kind or another. I don't see what personalities have to
That's false. They merely contain more ideas based on wider knowledge,
and more positive statements as opposed to negatives and as such are
more vulnerable to jealous individuals with time on their hands who
have "edited" a grand total of one unsaleable book from one unethical
publisher.
> do with it. But if you want me to stop claiming that most of what you
> write is wrong, start writing some right stuff. (Personally, I'm not
> holding my breath waiting for that to happen. I've waited nearly a
> decade and it hasn't happened yet to any noticeable degree.)
This is indeed the sort of language inadequate individuals learn to
use in banks: it's deliberately abstract in order to be proof against
criticism. The result of this sort of language at Northern Rock and
Lehmann brothers was widespread financial disaster except for the
superrich. You describe yourself as working for "banks and insurance
companies". Did you work for Northern Rock, and how many people did
you trash there? How much software did you write, and how much damage
did it do?
>
> <usual nonsense about Fascism snipped>
>
> --
> Richard Heathfield <http://www.cpax.org.uk>
> Email: -http://www. +rjh@
> "Usenet is a strange place" - dmr 29 July 1999
> Sig line vacant - apply within
|
|
0
|
|
|
|
Reply
|
spinoza1111 (3250)
|
10/23/2009 12:48:52 AM
|
|
On Oct 23, 2:48=A0am, Mark McIntyre <markmcint...@TROUSERSspamcop.net>
wrote:
> Corvus wrote:
> > I am looking for other ways to write the following in as few lines as
> > possible, but I think I have hit the limit...
>
> > x -=3D x/abs(x)
>
> Uh...you've written it in one line. The only less would be zero lines...
It's not a correct piece of software. It divides by zero when x is
zero. The signum function is defined as zero when x is zero.
|
|
0
|
|
|
|
Reply
|
spinoza1111 (3250)
|
10/23/2009 12:49:51 AM
|
|
On Oct 23, 12:04=A0am, Keith Thompson <ks...@mib.org> wrote:
> James Dow Allen <jdallen2...@yahoo.com> writes:
>
> > On Oct 22, 1:51=A0pm, Keith Thompson <ks...@mib.org> wrote:
> >> Rule of thumb: If a ?: operator can be written equivalently as an
> >> if-else statement, write it as an if-else statement (unless it's
> >> part of a macro definition).
>
> > I think we'd all agree that "cutesy" shortcuts to achieve a
> > false keystroke economy are wrong, but this statement goes much
> > too far. =A0It seems to assume that "if else" is more readable
> > than "? :" but that should *not* be the case for a C programmer.
>
> I was referring specifically to cases where a ?: operator appears at
> the top level of a statement expression, and the second and third
> operands' results are discarded. =A0For example:
>
> =A0 =A0 condition ? puts("A message") : puts("Another message");
>
> In my opinion, using ?: here is just silly; it's better written as:
>
> =A0 =A0 if (condition) {
> =A0 =A0 =A0 =A0 puts("A message");
> =A0 =A0 }
> =A0 =A0 else {
> =A0 =A0 =A0 =A0 puts("Another message");
> =A0 =A0 }
>
> or whatever brace style you prefer. =A0In cases like this, the use of
> the ?: operator tells me "I know what the ?: operator is, and you
> should be impressed."
It's one thing to be falsely, whiningly humble in a monastery, but to
be afraid to use a perfectly sensible construct in a corporation
because one doesn't want to be thought by inadequate people to be
"pretentious" is just absurd. One of the biggest problems with the
above code is the amount of vertical space it takes, which causes
simple functions to be partly hidden on small screens. It also doesn't
allow the puts call to be written once, saving whatever storage it
takes to express the puts call at runtime, whereas this does:
puts(cond?"You suck":"You don't suck");
Nor does it allow a further optimization in C Sharp only:
puts("You " + cond?"":"don't " + "suck")
In C:
puts("You %ssuck", cond?"":"don't ");
>
> > I often string together ?, : and/or && and || into an involved
> > expression, and add newlines and tabs to make it easy to read.
> > IMHO the if/else equivalent would be harder to read because of
> > all the "if/else" clutter.
>
> Can you give an example? =A0If it doesn't meet the criteria I mentioned
> above, so that the transformation from ?: to if-else is absolutely
> trivial, I probably wouldn't object. =A0I don't find "if" and "else" to
> be clutter; they're just part of the code.
>
> (But tabs? =A0Spaces only, please.)
>
> > Surely none of us prefer Cobol's
> > =A0 =A0ADD OVERTIME TO SALARY
> > or whatever it is, over C's
> > =A0 =A0salary +=3D overtime;
> > Not to extend the same courtesy to C's beautiful " ? : "
> > would be to patronize the beginning C programmer.
>
> --
> Keith Thompson (The_Other_Keith) ks...@mib.org =A0<http://www.ghoti.net/~=
kst>
> Nokia
> "We must do something. =A0This is something. =A0Therefore, we must do thi=
s."
> =A0 =A0 -- Antony Jay and Jonathan Lynn, "Yes Minister"
|
|
0
|
|
|
|
Reply
|
spinoza1111 (3250)
|
10/23/2009 1:01:25 AM
|
|
In <8bf892a5-797e-45b5-abba-5a1bb704d7de@x5g2000prf.googlegroups.com>,
spinoza1111 wrote:
> On Oct 23, 2:09 am, Richard Heathfield <r...@see.sig.invalid> wrote:
<snip>
>> It was a comment based on the observation that the majority of
>> articles posted under the account spinoza1...@yahoo.com contain
>> errors of one kind or another.
No, I didn't say that. I said: "It was a comment based on the
observation that the majority of articles posted under the account
spinoza11111@yahoo.com contain errors of one kind or another."
The difference is significant. If your newsreader can't quote
properly, learn to proof-read.
> That's false.
There you go, getting it wrong again.
<nonsense snipped>
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
|
|
0
|
|
|
|
Reply
|
rjh (10789)
|
10/23/2009 1:14:05 AM
|
|
spinoza1111 <spinoza1111@yahoo.com> writes:
> It's not a correct piece of software. It divides by zero when x is
> zero.
Would you describe:
x = *y;
as buggy code?
|
|
0
|
|
|
|
Reply
|
gwowen (518)
|
10/23/2009 5:57:01 AM
|
|
On 23 Oct, 02:14, Richard Heathfield <r...@see.sig.invalid> wrote:
> In <8bf892a5-797e-45b5-abba-5a1bb704d...@x5g2000prf.googlegroups.com>,
> spinoza1111 wrote:
> > On Oct 23, 2:09 am, Richard Heathfield <r...@see.sig.invalid> wrote:
> >> It was a comment based on the observation that the majority of
> >> articles posted under the account spinoza1...@yahoo.com contain
> >> errors of one kind or another.
>
> No, I didn't say that. I said: "It was a comment based on the
> observation that the majority of articles posted under the account
> spinoza11...@yahoo.com contain errors of one kind or another."
>
> The difference is significant. If your newsreader can't quote
> properly, learn to proof-read.
you got me. What *is* the difference? Google's mangled the address. Is
that the difference you are talking about?
|
|
0
|
|
|
|
Reply
|
nick_keighley_nospam (4574)
|
10/23/2009 7:40:20 AM
|
|
In <082d8863-f6c8-4d03-85c9-dcb3ac751970@s6g2000vbp.googlegroups.com>,
Nick Keighley wrote:
> On 23 Oct, 02:14, Richard Heathfield <r...@see.sig.invalid> wrote:
>> In
>> <8bf892a5-797e-45b5-abba-5a1bb704d...@x5g2000prf.googlegroups.com>,
>> spinoza1111 wrote:
>> > On Oct 23, 2:09 am, Richard Heathfield <r...@see.sig.invalid>
>> > wrote:
>
>> >> It was a comment based on the observation that the majority of
>> >> articles posted under the account spinoza1...@yahoo.com contain
>> >> errors of one kind or another.
>>
>> No, I didn't say that. I said: "It was a comment based on the
>> observation that the majority of articles posted under the account
>> spinoza11...@yahoo.com contain errors of one kind or another."
>>
>> The difference is significant. If your newsreader can't quote
>> properly, learn to proof-read.
>
> you got me. What *is* the difference? Google's mangled the address.
> Is that the difference you are talking about?
Yes.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
|
|
0
|
|
|
|
Reply
|
rjh (10789)
|
10/23/2009 7:49:44 AM
|
|
On 22 Oct, 22:14, Keith Thompson <ks...@mib.org> wrote:
> I'm sure that will look very simple after a few hours of study.
It will be /obvious/ after a few hours study.
|
|
0
|
|
|
|
Reply
|
nick_keighley_nospam (4574)
|
10/23/2009 7:54:42 AM
|
|
On 23 Oct, 02:01, spinoza1111 <spinoza1...@yahoo.com> wrote:
> On Oct 23, 12:04=A0am, Keith Thompson <ks...@mib.org> wrote:
> > James Dow Allen <jdallen2...@yahoo.com> writes:
> > > On Oct 22, 1:51=A0pm, Keith Thompson <ks...@mib.org> wrote:
> > >> Rule of thumb: If a ?: operator can be written equivalently as an
> > >> if-else statement, write it as an if-else statement (unless it's
> > >> part of a macro definition).
I hope I never have to code to a standard like this.
> > > I think we'd all agree that "cutesy" shortcuts to achieve a
> > > false keystroke economy are wrong, but this statement goes much
> > > too far. =A0It seems to assume that "if else" is more readable
> > > than "? :" but that should *not* be the case for a C programmer.
>
> > I was referring specifically to cases where a ?: operator appears at
> > the top level of a statement expression, and the second and third
> > operands' results are discarded. =A0For example:
>
> > =A0 =A0 condition ? puts("A message") : puts("Another message");
>
> > In my opinion, using ?: here is just silly; it's better written as:
>
> > =A0 =A0 if (condition) {
> > =A0 =A0 =A0 =A0 puts("A message");
> > =A0 =A0 }
> > =A0 =A0 else {
> > =A0 =A0 =A0 =A0 puts("Another message");
> > =A0 =A0 }
>
> > or whatever brace style you prefer. =A0In cases like this, the use of
> > the ?: operator tells me "I know what the ?: operator is, and you
> > should be impressed."
>
<snip sociology>
> =A0One of the biggest problems with the
> above code is the amount of vertical space it takes, which causes
> simple functions to be partly hidden on small screens. It also doesn't
> allow the puts call to be written once, saving whatever storage it
> takes to express the puts call at runtime, whereas this does:
I think it's just ugly and unclear
> puts(cond?"You suck":"You don't suck");
>
> Nor does it allow a further optimization in C Sharp only:
>
> puts("You " + cond?"":"don't " + "suck")
>
> In C:
>
> puts("You %ssuck", cond?"":"don't ");
printf ("You %ssuck", cond ? "" : "don't ");
<snip>
|
|
0
|
|
|
|
Reply
|
nick_keighley_nospam (4574)
|
10/23/2009 8:04:31 AM
|
|
On Oct 23, 1:57=A0pm, Gareth Owen <gwo...@gmail.com> wrote:
> spinoza1111<spinoza1...@yahoo.com> writes:
> > It's not a correct piece of software. It divides by zero when x is
> > zero.
>
> Would you describe:
>
> x =3D *y;
>
> as buggy code?
Not as such, given that all I know is that x is set to y,
dereferenced. Sure, y might not be dereferenceable and may cause a
segment fault.
But this does NOT excuse coding crap like this:
return x>0 ? 1 : -1;
or this:
if (x>0) return 1; return -1;
[and note that compared to the egregious error in both the above code
snippets, it matters not in the slightest whether the programmer has
used ?:, or if].
This is KNOWN to be probable crap because independent of programming
there exists a signum function, and the code communicates:
(1) An intent to "do" signum
(2) An ignorant or uncaring disregard for the case of x=3D=3D0
Don't worry about whether your code will seem "pretentious" to some
Troglodyte because he doesn't like ?:. Just get it right.
|
|
0
|
|
|
|
Reply
|
spinoza1111 (3250)
|
10/23/2009 8:39:48 AM
|
|
Nick Keighley <nick_keighley_nospam@hotmail.com> writes:
> printf ("You %ssuck", cond ? "" : "don't ");
printf("I see %u ship%s.\n",nships, nships == 1 ? "" : "s");
|
|
0
|
|
|
|
Reply
|
gwowen (518)
|
10/23/2009 10:17:53 AM
|
|
spinoza1111 <spinoza1111@yahoo.com> writes:
> Not as such, given that all I know is that x is set to y,
> dereferenced. Sure, y might not be dereferenceable and may cause a
> segment fault.
Its fine if you know that y is pointing somewhere valid.
> But this does NOT excuse coding crap like this:
>
> return x>0 ? 1 : -1;
Its fine if you know that x is not zero.
It's all about the domain of the code fragment. We didn't get the
context so we can't say if its buggy or not. For all we can tell, the
original code fragment was wrapped up as.
if(x !=0) {
x -= x / abs(x);
}
Summary: Unless you know the context, you can't say whether either
code fragment is buggy or not.
|
|
0
|
|
|
|
Reply
|
gwowen (518)
|
10/23/2009 10:23:35 AM
|
|
On Oct 23, 6:23=A0pm, Gareth Owen <gwo...@gmail.com> wrote:
> spinoza1111<spinoza1...@yahoo.com> writes:
> > Not as such, given that all I know is that x is set to y,
> > dereferenced. Sure, y might not be dereferenceable and may cause a
> > segment fault.
>
> Its fine if you know that y is pointing somewhere valid.
>
> > But this does NOT excuse coding crap like this:
>
> > return x>0 ? 1 : -1;
>
> Its fine if you know that x is not zero. =A0
We don't know that. And even if we do (if some "end user" reassures us
that this is so), that can change without notice, and it doesn't hurt
to implement a more easily documented mathematical function...even if
the end user may not know the "signum" function. This is because end
users and requirements change, faster than mathematical terminology.
It never hurts to get it right, UNLESS the end user requires that the
value be -1 (or 1) for x=3D=3D0. I got the impression that this was not
the case, that instead nobody even thought about x=3D=3D0. And, the
original code just crashes on divide by zero in this case.
>
> It's all about the domain of the code fragment. We didn't get the
> context so we can't say if its buggy or not. =A0For all we can tell, the
> original code fragment was wrapped up as.
>
> if(x !=3D0) {
> =A0 x -=3D x / abs(x);
>
> }
>
> Summary: Unless you know the context, you can't say whether either
> =A0 =A0 =A0 =A0 =A0code fragment is buggy or not.
|
|
0
|
|
|
|
Reply
|
spinoza1111 (3250)
|
10/23/2009 11:46:07 AM
|
|
On Oct 23, 1:57=A0pm, Gareth Owen <gwo...@gmail.com> wrote:
> spinoza1111<spinoza1...@yahoo.com> writes:
> > It's not a correct piece of software. It divides by zero when x is
> > zero.
>
> Would you describe:
>
> x =3D *y;
>
> as buggy code?
In terms of modern OO practice, x =3D *y is buggy code. This is because
both C Sharp and Java define a subset of all possible programs such
that references are always and everywhere managed, not referencing
storage outside of a known error unless, of course, the runtime
virtual machine is itself buggy; the runtime VM machine will be buggy
with small if nonzero probability p while applications code will be
buggy with a much larger probability P>=3D10*p.
In terms of modern OO practice, C code is buggy code in all cases. The
probability PP of bugginess of any arbitrary snippet of C code is
>=3D10p where p is the probability of managed C Sharp code.
Furthermore,
return x>0?1:-1;
is a prima facie bug because the closest mathematical function to what
it does is signum, and it gets signum wrong. Neither programmers nor
end users have the right to create new mathematical functions *ex
nihilo*. A competent programmer, when told to "return 1 when x is
greater than zero, and return -1 when x is less than zero", would ask
"what the goddamn hell should I return when x is zero, dorkwad?"
Managers of software used to brag that "every line of code written in
my 'shop' must have a Biznez Case or else because I'm such a studly
dudley practical man, and I don't put up with no monkey business from
a bunch of faggot math majors", or words to that effect.
I would change that. I would say that ideally, every line of code
would have a referent outside of programming, preferably to
mathematics. That's because in an ideal world there would be no
"business", just meeting human needs.
|
|
0
|
|
|
|
Reply
|
spinoza1111 (3250)
|
10/23/2009 11:58:36 AM
|
|
Richard Heathfield <rjh@see.sig.invalid> writes:
> In <082d8863-f6c8-4d03-85c9-dcb3ac751970@s6g2000vbp.googlegroups.com>,
> Nick Keighley wrote:
>> On 23 Oct, 02:14, Richard Heathfield <r...@see.sig.invalid> wrote:
>>> In
>>> <8bf892a5-797e-45b5-abba-5a1bb704d...@x5g2000prf.googlegroups.com>,
>>> spinoza1111 wrote:
>>> > On Oct 23, 2:09 am, Richard Heathfield <r...@see.sig.invalid>
>>> > wrote:
>>> >> It was a comment based on the observation that the majority of
>>> >> articles posted under the account spinoza1...@yahoo.com contain
>>> >> errors of one kind or another.
>>>
>>> No, I didn't say that. I said: "It was a comment based on the
>>> observation that the majority of articles posted under the account
>>> spinoza11...@yahoo.com contain errors of one kind or another."
>>>
>>> The difference is significant. If your newsreader can't quote
>>> properly, learn to proof-read.
>>
>> you got me. What *is* the difference? Google's mangled the address.
>> Is that the difference you are talking about?
>
> Yes.
Google Groups always mangles e-mail addresses like thot, supposedly
to make it more difficult for spammers to harvest addresses.
(Note that this affected the second quotation of the sentence as
well as the first, because Nick also posts through Google Groups.)
Since there's no real risk of confusion, it was perfectly reasonable
to leave it alone rather than manually correct it.
This is perhaps the most trivial offense Nilges has committed here,
and I'm surprised you bothered to note it.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
|
|
0
|
|
|
|
Reply
|
kst-u (21469)
|
10/23/2009 2:18:49 PM
|
|
On Oct 23, 1:20=A0am, Richard Heathfield <r...@see.sig.invalid> wrote:
> One man's stylistic fetish is another man's readability-friendly
> constraint:
>
> > [fragment that uses 3 lines]
>
> > into
>
> > =A0[someone else's 3 line fragment]
>
> > I don't like the latter
>
> I don't like either of them. I like:
>
> [10 or 11 line fragment]
I was happy to see in this thread that I'm not the only who
finds it virtuous to conserve vertical space. Evidently
Mr. Heathfield is not in our select company! :-)
Richard, are you one of these people with 20-10 vision who
view code in the smallest font available?
First: Switch to TRUE style; you can save 3 lines just
by placing the braces correctly in your fragment. I was
already approaching middle-age when I switched to TRUE,
and even if you don't feel like switching in your
personal code, please watch your C language here: there
are children present!
One "wasted" line in Richard's fragment I *don't*
object to: he replaced
> return Complicated;
with
> newstatus =3D Complicated;
> return newstatus;
This will come in handy when you need to debug.
.... As you will since you're not using True Style. :-)
Hoping I added enough smiley-faces to avoid giving offense,
Yours truly,
James
|
|
0
|
|
|
|
Reply
|
jdallen2000 (489)
|
10/23/2009 2:24:10 PM
|
|
Gareth Owen <gwowen@gmail.com> might have writ, in news:87skdbdwvm.fsf@linux-8rq8.site:
> James Dow Allen <jdallen2000@yahoo.com> writes:
>
>> /* Return the median of 3 numbers */
>> int median3(int a, int b, int c)
>> {
>> return a<b ? b<c ? b
>> : a<c ? c : a
>> : c<b ? b
>> : c<a ? c : a;
>> }
>
> I love ASCII art. What's it supposed to be? ;)
Touche (or rather Touché -- I can't do UTC).
I should have arranged the white space better.
The "real" code, I'm not too shy to admit, was actually
return a < b ? b < c ? b : a < c ? c : a : c < b ? b : c < a ? c : a;
But I *had* to edit it somehow for the post since
Groups.DoNoEvil.com was otherwise going to break the line.
(I'm not posting this message from DoNoEvil.)
I would *NOT* jam this logic into a single line if I
thought anyone would ever need to read it, but here,
surely the comment
/* Return the median of 3 numbers */
tells the reader everything he needs to know about
the details, without wasting vertical space!
(And if someone counters with "What if there's a bug?"
my answer will be "Same to you, buddy!")
Staring at these fragments I'm wondering if "if/else"
*might* be more readable than "?/:" after all -- *not*
because ":" is less clear than "else" but because it
uses *less ink* (or less phosphors) and thus doesn't
stand out as well!
Given the interest in rewriting median3(), I'm surprised
no one offered:
> double fmedian3(double a, double b, double c)
> {
> return a + b + c
> - fmax(fmax(a, b), c)
> - fmin(fmin(a, b), c);
> }
>
> Get yourself a new compiler if it can't even
> optimize *this* !
By the way, I found the median3() in old source with the command:
cat */*.c | tr ";\n" "\n\r" | grep "?.*?.*?" | tr "\n\r" ";\n"
Another example that turned up with that was
in the code that creates pages for the
Fabulous Pedigree website
http://fabpedigree.com/s098/f811410.htm
> fprintf(wpfd, "<hr> %s%s%s:%s \n",
> Labb,
> Partnerposs ? "poss. " : "",
> Abstractroot
> ? (cnt > 1
> ? ("\"Partners\"")
> : ("\"Partner\""))
> : cnt > 1
> ? (ismale ? "Wives/Partners" : "Husbands/Partners")
> : (ismale ? "Wife/Partner" : "Husband/Partner"),
> Labe);
James Dow Allen
|
|
0
|
|
|
|
Reply
|
gmail1217 (37)
|
10/23/2009 2:56:38 PM
|
|
James Dow Allen <gmail@jamesdowallen.nospam> writes:
>return a < b ? b < c ? b : a < c ? c : a : c < b ? b : c < a ? c : a;
The following experiment in formatting is following the rule
that each colon has the same indentation as the
corresponding question mark:
return a < b ? b < c ? b
: a < c ? c
: a
: c < b ? b
: c < a ? c
: a;
Thus, for every question mark, the eye can easily find the
following parts:
1st operand: left of the �?�
colon: first colon below the �?�
2nd operand: between the �?� and the �:�
3rd operand: after the �:� until to the point
where the indentation is left of the �?� or the
full expression ends.
|
|
0
|
|
|
|
Reply
|
ram (2827)
|
10/23/2009 4:23:49 PM
|
|
Keith Thompson <kst-u@mib.org> writes:
> James Dow Allen <jdallen2000@yahoo.com> writes:
>> On Oct 22, 1:51 pm, Keith Thompson <ks...@mib.org> wrote:
>>> Rule of thumb: If a ?: operator can be written equivalently as an
>>> if-else statement, write it as an if-else statement (unless it's
>>> part of a macro definition).
>>
>> I think we'd all agree that "cutesy" shortcuts to achieve a
>> false keystroke economy are wrong, but this statement goes much
>> too far. It seems to assume that "if else" is more readable
>> than "? :" but that should *not* be the case for a C programmer.
>
> I was referring specifically to cases where a ?: operator appears at
> the top level of a statement expression, and the second and third
> operands' results are discarded. For example:
>
> condition ? puts("A message") : puts("Another message");
>
> In my opinion, using ?: here is just silly; it's better written as:
>
> if (condition) {
> puts("A message");
> }
> else {
> puts("Another message");
> }
>
> or whatever brace style you prefer. In cases like this, the use of
> the ?: operator tells me "I know what the ?: operator is, and you
> should be impressed."
Actually it doesn't. It says here is a piss simple little value switch
that I dont need to spread over 6 lines when I can use one.
If a c programmer has difficulty reading
,----
| a=b?c:d;
`----
then he should give up.
|
|
0
|
|
|
|
Reply
|
rgrdev_ (1087)
|
10/23/2009 4:26:45 PM
|
|
Richard <rgrdev_@gmail.com> writes:
> If a c programmer has difficulty reading
> ,----
> | a=b?c:d;
> `----
> then he should give up.
I understand what that does. However, for those of us who read left
to right, the problem is the ? modifies what the = does, so I have to
mentally backtrack.
As I scan the line, my mind first sees
a = b ...
Thinks: "OK, I'm setting a to the value of b" ...
a = b ?
Thinks: "Oh, no look a, '?'. I'm not setting a to b at all.
b is a condition that controls whether to set a to c or d."
When parsed from left to right (as those of us who use Indo-European
languages do) its a tortuous construction. Yoda-code.
"Set A when condition B to C, otherwise D."
"When 900 Years Old You Reach Look This Good You Will Not"
|
|
0
|
|
|
|
Reply
|
gwowen (518)
|
10/23/2009 4:56:15 PM
|
|
Gareth Owen <gwowen@gmail.com> writes:
> Richard <rgrdev_@gmail.com> writes:
>
>> If a c programmer has difficulty reading
>> ,----
>> | a=b?c:d;
>> `----
>> then he should give up.
>
> I understand what that does. However, for those of us who read left
> to right, the problem is the ? modifies what the = does, so I have to
> mentally backtrack.
>
> As I scan the line, my mind first sees
>
> a = b ...
>
> Thinks: "OK, I'm setting a to the value of b" ...
>
> a = b ?
>
> Thinks: "Oh, no look a, '?'. I'm not setting a to b at all.
> b is a condition that controls whether to set a to c or d."
>
> When parsed from left to right (as those of us who use Indo-European
> languages do) its a tortuous construction. Yoda-code.
>
> "Set A when condition B to C, otherwise D."
> "When 900 Years Old You Reach Look This Good You Will Not"
That's all well and good but I, and anyone that has spent any time with C
should IMO, read it as "assign to a the result of the logical expression
following" .. or assign to a depending on b. It really is straightforward.
Especially useful in embedded in expressions.
printf("%s\n", (fArrived?"Hello":"Goodbye"));
Clean, obvious, efficient, no cluttering namespace.
A good programmer should never program to the lowest common denominator
and should use the features of the language.
--
"Avoid hyperbole at all costs, its the most destructive argument on
the planet" - Mark McIntyre in comp.lang.c
|
|
0
|
|
|
|
Reply
|
rgrdev_ (1087)
|
10/23/2009 5:09:44 PM
|
|
In
<13a223a9-c307-4bcd-95a7-ef46b6fada62@g22g2000prf.googlegroups.com>,
James Dow Allen wrote:
<snip>
> I was happy to see in this thread that I'm not the only who
> finds it virtuous to conserve vertical space. Evidently
> Mr. Heathfield is not in our select company! :-)
Right. I've found that I can afford millions of lines of vertical
space. It's much cheaper than is commonly believed.
> Richard, are you one of these people with 20-10 vision who
> view code in the smallest font available?
No, if anything I use a slightly oversized font. But I try to keep my
functions relatively short, and in any case I am capable of pressing
PgDn without then instantly forgetting everything I was just looking
at.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
|
|
0
|
|
|
|
Reply
|
rjh (10789)
|
10/23/2009 5:28:57 PM
|
|
In <87eioucamo.fsf@linux-8rq8.site>, Gareth Owen wrote:
<snip>
> When parsed from left to right (as those of us who use Indo-European
> languages do) its a tortuous construction. Yoda-code.
Or "Yode", a neologism to coin.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
|
|
0
|
|
|
|
Reply
|
rjh (10789)
|
10/23/2009 5:30:58 PM
|
|
"Gareth Owen" <gwowen@gmail.com> wrote in message
news:87eioucamo.fsf@linux-8rq8.site...
> Richard <rgrdev_@gmail.com> writes:
>
>> If a c programmer has difficulty reading
>> ,----
>> | a=b?c:d;
>> `----
>> then he should give up.
>
> I understand what that does. However, for those of us who read left
> to right, the problem is the ? modifies what the = does, so I have to
> mentally backtrack.
>
> As I scan the line, my mind first sees
>
> a = b ...
>
> Thinks: "OK, I'm setting a to the value of b" ...
>
> a = b ?
>
> Thinks: "Oh, no look a, '?'. I'm not setting a to b at all.
> b is a condition that controls whether to set a to c or d."
>
> When parsed from left to right (as those of us who use Indo-European
> languages do) its a tortuous construction. Yoda-code.
You might have trouble with
a = b + c
then. I tend to enclose these ?: expressions in parenthesis as I haven't a
clue how ?: interacts with other operators:
a = (b ? c : d)
--
bartc
|
|
0
|
|
|
|
Reply
|
bartc (783)
|
10/23/2009 6:55:15 PM
|
|
In article <hbso0o$sdl$1@news.eternal-september.org>,
Richard <rgrdev_@gmail.com> wrote:
> Gareth Owen <gwowen@gmail.com> writes:
>
> > Richard <rgrdev_@gmail.com> writes:
> >
> >> If a c programmer has difficulty reading
> >> ,----
> >> | a=b?c:d;
> >> `----
> >> then he should give up.
> >
> > I understand what that does. However, for those of us who read left
> > to right, the problem is the ? modifies what the = does, so I have to
> > mentally backtrack.
> >
> > As I scan the line, my mind first sees
> >
> > a = b ...
> >
> > Thinks: "OK, I'm setting a to the value of b" ...
> >
> > a = b ?
> >
> > Thinks: "Oh, no look a, '?'. I'm not setting a to b at all.
> > b is a condition that controls whether to set a to c or d."
> >
> > When parsed from left to right (as those of us who use Indo-European
> > languages do) its a tortuous construction. Yoda-code.
> >
> > "Set A when condition B to C, otherwise D."
> > "When 900 Years Old You Reach Look This Good You Will Not"
>
> That's all well and good but I, and anyone that has spent any time with C
> should IMO, read it as "assign to a the result of the logical expression
> following" .. or assign to a depending on b. It really is straightforward.
>
> Especially useful in embedded in expressions.
>
> printf("%s\n", (fArrived?"Hello":"Goodbye"));
>
> Clean, obvious, efficient, no cluttering namespace.
>
> A good programmer should never program to the lowest common denominator
> and should use the features of the language.
But don't emulate perl programmers, though. Their one goal in life is to
reduce every program to a .
--
Tim
"That excessive bail ought not to be required, nor excessive fines imposed,
nor cruel and unusual punishments inflicted" -- Bill of Rights 1689
|
|
0
|
|
|
|
Reply
|
timstreater (943)
|
10/23/2009 8:48:43 PM
|
|
Richard <rgrdev_@gmail.com> writes:
> That's all well and good but I, and anyone that has spent any time
> with C should IMO, read it as "assign to a the result of the logical
> expression following" .. or assign to a depending on b. It really is
> straightforward.
I know its straightforward. It's still clunky and unclear. If you
really want that interpretation, but some brackets in there. Program
as you if expect other people to read your code. Express your intent,
and don't expect everyone to enjoy C's more pointless idioms as much
as you do.
> A good programmer should never program to the lowest common
> denominator and should use the features of the language.
You should use the features of the language when there is a benefit to
doing so, other than less typing. That way, Perl Golf lies. There's
no benefit to your code, except that is slightly harder to parse.
If you write code to demonstrate how smart you are, or how much of the
language you have mastered, you'll write unmaintainable code. Master
the language, but then exhibit good taste, and respect for people
who've not reached your level of mastery.
Good programming involves writing code that is easy to understand by
someone who is not a good programmer. Much as good technical writing
is writing that is easy to understand by someone who does not know the
product as well as the writer.
|
|
0
|
|
|
|
Reply
|
gwowen (518)
|
10/24/2009 9:10:17 AM
|
|
"bartc" <bartc@freeuk.com> writes:
> a = b + c
Here, the b takes part in the assignment. It's one of the things that
gets assigned -- sure you modify it first, but its still in the
mix. It would have to be a compatible type, for example.
I can read it as "assign b to a then add c".
As opposed to
double a,b,c;
double *p;
a = p ? b : c;
The beginning of that looks like the assignment of a pointer to a
double.
> then. I tend to enclose these ?: expressions in parenthesis as I
> haven't a clue how ?: interacts with other operators:
>
> a = (b ? c : d)
I always bracket these expressions too. The mental parser is given a
nice clear sign of what's going on. Result, clarity.
|
|
0
|
|
|
|
Reply
|
gwowen (518)
|
10/24/2009 9:16:26 AM
|
|
"user923005" <dcorbit@connx.com> ha scritto nel messaggio
news:c70d29fe-48dc-44b8-9995-95dcf59df129@s21g2000prm.googlegroups.com...
>e_type median3(e_type a, e_type b, e_type c)
>{
> return (a < b) ? ((b < c) ? b : ((a < c) ? c : a)) : ((a < c) ?
>a : ((b < c) ? c : b));
>}
all your methods of write the above is for me not readble
only this is seems ok
e_type median3(e_type a, e_type b, e_type c)
{return a<b ? (b<c ? b : (a<c ? c : a)) :
(a<c ? a : (b<c ? c : b)) ;
}
but no one propose it
-------------a<b
a b c
|--|--| (b<c) -> b
a c b
|--|--| (a<c) -> c
c a b
|--|--| -> a
-------------a>b
b a c
|--|--| (a<c) -> a
b c a
|--|--| (b<c) -> c
-> b
|
|
0
|
|
|
|
Reply
|
io_x
|
10/24/2009 9:54:05 AM
|
|
"Gareth Owen" <gwowen@gmail.com> ha scritto nel messaggio
news:8763a5w3rp.fsf@linux-8rq8.site...
> "bartc" <bartc@freeuk.com> writes:
>
>> a = b + c
>
> Here, the b takes part in the assignment. It's one of the things that
> gets assigned -- sure you modify it first, but its still in the
> mix. It would have to be a compatible type, for example.
>
> I can read it as "assign b to a then add c".
i read that "a=b+c" and if i think about that i see
i see "s1=b+c" "a=s1"
> As opposed to
>
> double a,b,c;
> double *p;
>
> a = p ? b : c;
>
> The beginning of that looks like the assignment of a pointer to a
> double.
i write it like "a= (p!=0? b: c);"
>> then. I tend to enclose these ?: expressions in parenthesis as I
>> haven't a clue how ?: interacts with other operators:
>>
>> a = (b ? c : d)
>
> I always bracket these expressions too. The mental parser is given a
> nice clear sign of what's going on. Result, clarity.
i agree. But if someone write many b?c:d it is possible that read better
a=b?c:d;
|
|
0
|
|
|
|
Reply
|
io_x
|
10/24/2009 10:20:56 AM
|
|
"Gareth Owen" <gwowen@gmail.com> ha scritto nel messaggio
news:87aazhw41y.fsf@linux-8rq8.site...
i'm agree with you;
if there are many complex way of write something;
all became not readable
> Richard <rgrdev_@gmail.com> writes:
>> A good programmer should never program to the lowest common
>> denominator and should use the features of the language.
>
> You should use the features of the language when there is a benefit to
> doing so, other than less typing. That way, Perl Golf lies. There's
> no benefit to your code, except that is slightly harder to parse.
>
> If you write code to demonstrate how smart you are, or how much of the
> language you have mastered, you'll write unmaintainable code. Master
> the language, but then exhibit good taste, and respect for people
> who've not reached your level of mastery.
>
> Good programming involves writing code that is easy to understand by
> someone who is not a good programmer. Much as good technical writing
> is writing that is easy to understand by someone who does not know the
> product as well as the writer.
|
|
0
|
|
|
|
Reply
|
io_x
|
10/24/2009 10:20:59 AM
|
|
Keith Thompson <kst-u@mib.org> writes:
> James Dow Allen <jdallen2000@yahoo.com> writes:
>> On Oct 22, 1:51 pm, Keith Thompson <ks...@mib.org> wrote:
>>> Rule of thumb: If a ?: operator can be written equivalently as an
>>> if-else statement, write it as an if-else statement (unless it's
>>> part of a macro definition).
>>
>> I think we'd all agree that "cutesy" shortcuts to achieve a
>> false keystroke economy are wrong, but this statement goes much
>> too far. It seems to assume that "if else" is more readable
>> than "? :" but that should *not* be the case for a C programmer.
>
> I was referring specifically to cases where a ?: operator appears at
> the top level of a statement expression, and the second and third
> operands' results are discarded. For example:
>
> condition ? puts("A message") : puts("Another message");
>
> In my opinion, using ?: here is just silly; it's better written as:
>
> if (condition) {
> puts("A message");
> }
> else {
> puts("Another message");
> }
Better written as:
puts(condition ? "A message" : "Another message");
> or whatever brace style you prefer. In cases like this, the use of
> the ?: operator tells me "I know what the ?: operator is, and you
> should be impressed."
The original ?: example used ?: only for control flow, not for
selection of values. So it doesn't tell me that the author knows
that it has that latter use. The fact they avoided my version
tells me that probably they don't. So we'd both flag the line,
for mostly the same reason, but my terseness pushes me to my
one-liner rather than
>> I often string together ?, : and/or && and || into an involved
>> expression, and add newlines and tabs to make it easy to read.
>> IMHO the if/else equivalent would be harder to read because of
>> all the "if/else" clutter.
>
> Can you give an example? If it doesn't meet the criteria I mentioned
> above, so that the transformation from ?: to if-else is absolutely
> trivial, I probably wouldn't object. I don't find "if" and "else" to
> be clutter; they're just part of the code.
Sometimes they make the function easier to understand as they
clearly and cleanly frame off sections which can be considered
separately. That's not clutter at all.
> (But tabs? Spaces only, please.)
A coding standard which is 100% strict about how wide a tab is
may also approve or demand the use of tabs.
I don't personally care - I press 'tab' in emacs, and it makes
the code conform to the coding standard in effect at the time.
Phil
--
Any true emperor never needs to wear clothes. -- Devany on r.a.s.f1
|
|
0
|
|
|
|
Reply
|
thefatphil_demunged (1558)
|
10/24/2009 11:32:43 AM
|
|
Gareth Owen <gwowen@gmail.com> writes:
> Nick Keighley <nick_keighley_nospam@hotmail.com> writes:
>
>> printf ("You %ssuck", cond ? "" : "don't ");
>
> printf("I see %u ship%s.\n",nships, nships == 1 ? "" : "s");
printf("I see %u ship%s.\n", nships, "s"+(nships==1));
Phil
--
Any true emperor never needs to wear clothes. -- Devany on r.a.s.f1
|
|
0
|
|
|
|
Reply
|
thefatphil_demunged (1558)
|
10/24/2009 11:44:43 AM
|
|
On Fri, 23 Oct 2009 00:42:20 +0200, Moi wrote:
> On Thu, 22 Oct 2009 15:07:58 -0700, user923005 wrote:
>
>> On Oct 22, 2:24 pm, Moi <r...@invalid.address.org> wrote:
Next attempt (a bit inspired by de Bruijn numbers ...) :
*****************************************************/
int median3x(int a,int b,int c)
{
/* 2.0 1.1 0.2 0 */
switch( (0x2148U >> (idx=(((a>b)<<1)+((b>c)<<2)+((c>a)<<3)))) &3) {
case 0: return a;
case 1: return b;
case 2: return c;
}
}
***********************/
Still want to get rid of that switch...
AvK
|
|
0
|
|
|
|
Reply
|
root32 (398)
|
10/24/2009 12:33:40 PM
|
|
On Oct 24, 5:10=A0pm, Gareth Owen <gwo...@gmail.com> wrote:
> Richard <rgrd...@gmail.com> writes:
> > That's all well and good but I, and anyone that has spent any time
> > with C should IMO, read it as "assign to a the result of the logical
> > expression following" .. or assign to a depending on b. It really is
> > straightforward.
>
> I know its straightforward. =A0It's still clunky and unclear. =A0If you
> really want that interpretation, but some brackets in there. =A0Program
> as you if expect other people to read your code. Express your intent,
> and don't expect everyone to enjoy C's more pointless idioms as much
> as you do.
The idiom isn't "pointless". It shows in fact that logic can be as
elegantly expressed as mathematics. It's one step away from Cobol.
>
> > A good programmer should never program to the lowest common
> > denominator and should use the features of the language.
>
> You should use the features of the language when there is a benefit to
> doing so, other than less typing. =A0That way, Perl Golf lies. =A0There's
> no benefit to your code, except that is slightly harder to parse.
>
> If you write code to demonstrate how smart you are, or how much of the
> language you have mastered, you'll write unmaintainable code. =A0Master
> the language, but then exhibit good taste, and respect for people
> who've not reached your level of mastery.
It's an Urban Legend that the software crisis was caused by
"pretentious" programmers using "obscure" constructs in order to "show
how smart they were".
In actuality, it was caused by savage managers who drove programmers
to ship at places like IBM in 1965 and Apple in 1981, not giving a
fuck about the damage they caused to people's lives in their greed.
It meant that many programmers were unfamiliar with the languages they
used, being thrown with too little training on Death March projects
with insanse deadlines.
It is now accepted as a condition of employment that managers may make
absurd claims as to the doability of systems by such and such a date
in a forty hour week, and that the programmers will work 120 hour
weeks to make the deadline prediction come true and the manager look
good.
As a result, programmers hate their jobs and their lives, and the
notion of joyously coding
intSignum =3D intX > 0 ? 1 : (intX < 0 ? -1 : 0)
as opposed to this crap
if (s>0) return 1; return -1;
is now "pretentious". The former code snippet offends brutalized
programmers for the same reason people here confuse complete sentence
structure and accurate spelling with verbosity.
>
> Good programming involves writing code that is easy to understand by
> someone who is not a good programmer. =A0Much as good technical writing
> is writing that is easy to understand by someone who does not know the
> product as well as the writer.
So runs the hymnbook. The problem is that such boilerplate ignores the
fact that "easy to understand" is not itself a simple concept. The
fact is that some programmers are so brutalized and so subject to food
and other forms of addiction, that they labor to understand almost
anything, and efforts to clarify only confuse. They then use a
remythologised Urban Legend of "structured programming" to mean
"something that fits my prejudices and that I understand without
mental effort".
[Such as an implementation of signum that divides by zero when x is
zero.]
It would take a Habermas to show the fundamental contradiction in
software development, but I shall try. Habermas, a German philosopher,
draws a distinction between language used to make money (the language
of business) and language used when discussing affairs between friends
in what he calls "civil" society, a conversation where we try to
arrive at scientific or political truth without worrying about
economic success or failure.
Gerald (The Psychology of Computer Programming) Weinberg discovered
that in the "structured walkthough", the fair, dialogic, and open
conversation typical of friends agreeing, or agreeing to disagree, in
a sidewalk cafe was more productive in commercial software than the
hiding of information, personality destruction, and competitiveness
characteristic of business.
Years later, "open source" found that people were more productive when
coding for free and not looking over their shoulders to see if their
fat salaries were under threat, since the fat salaries weren't there.
In parts of open source, Habermasian civil society makes the process
fairer and less competitive, a common search for truth (something that
works).
Dijsktra, finally, discovered that debugging is a matter of applying
the scientific method; but the prevelance of Fundamentalist religion
and various forms of cultish denial (Holocaust denial, denial that
Shakespeare wrote "Shakespeare", Creationism and Zionism) amongst
technical people show that they are unclear on the concept of
scientific method and prefer a sort of folklore in programming, which
includes saws such as "keep it simple", saws that have the property
that their referents are vague.
Owing to the fact that most software conversations take place in the
competitive business arena, they are ridden by hypercompetitive
nastiness, which also infects these conversations here because so many
people crawl in here brutalized by capitalism and anxious to retrieve
their lost manhood by being bullies. Also, it's quite possible that
some people, who post compulsively and continuously, are being paid to
trash this conversation, transforming it from an adult, civil and
Habermasian search for agreement and truth to howling at the
moon...lest these threads turn out to be a basis for labor solidarity
and organization.
Of course, most Americans and UK subjects have no concept whatsoever
of Habermas' distinction between biz-talk and a common search for
truth in civil society. They are taught instead that in the modern,
globalized-capitalist world, enormous fortunes are made by brilliant
men far more talented than they, despite the fact that Tim Berners-Lee
really screwed up the design of the Internet and that Bill Gates could
not even program Donkey Kong.
Furthermore, popular culture (cf Zizek) can be usefully viewed as
proposing to destroy the space of civil conversation, and replace it
with dreams that in Adorno's words have no dreams: movies, substance
abuse and trivial bullshit instead of a common search for truth.
|
|
0
|
|
|
|
Reply
|
spinoza1111 (3250)
|
10/24/2009 12:53:12 PM
|
|
On Fri, 23 Oct 2009 00:42:20 +0200, Moi wrote:
> On Thu, 22 Oct 2009 15:07:58 -0700, user923005 wrote:
>
>> On Oct 22, 2:24 pm, Moi <r...@invalid.address.org> wrote:
Hope the compiler will see the CSE in this one:
***********************************/
int median3(int a,int b,int c)
{
/* 2.0 1.1 0.2 0 */
return (( (0x2148U >> ((((a>b)<<1)+((b>c)<<2)+((c>a)<<3)))) &3) ==0)*a
+ (( (0x2148U >> ((((a>b)<<1)+((b>c)<<2)+((c>a)<<3)))) &3) ==1)*b
+ (( (0x2148U >> ((((a>b)<<1)+((b>c)<<2)+((c>a)<<3)))) &3) ==2)*c
;
}
/**********************************
AvK
|
|
0
|
|
|
|
Reply
|
root32 (398)
|
10/24/2009 12:54:31 PM
|
|
On Sat, 24 Oct 2009 14:33:40 +0200, Moi wrote:
Oops, still some scaffolding to remove:
> switch( (0x2148U >> (idx=(((a>b)<<1)+((b>c)<<2)+((c>a)<<3)))) &3) { case
switch( (0x2148U >> ((((a>b)<<1)+((b>c)<<2)+((c>a)<<3)))) &3) { case
AvK
|
|
0
|
|
|
|
Reply
|
root32 (398)
|
10/24/2009 12:58:41 PM
|
|
Phil Carmody <thefatphil_demunged@yahoo.co.uk> writes:
> Gareth Owen <gwowen@gmail.com> writes:
>> Nick Keighley <nick_keighley_nospam@hotmail.com> writes:
>>
>>> printf ("You %ssuck", cond ? "" : "don't ");
>>
>> printf("I see %u ship%s.\n",nships, nships == 1 ? "" : "s");
>
> printf("I see %u ship%s.\n", nships, "s"+(nships==1));
While we are composing variations on this theme:
printf("I see %u ship%.*s.\n", nships, nships != 1, "s");
but in practise I do it Gareth's way because I don't want the code to
depend in the length of the plural ending; even though it is fixed for
any one word.
--
Ben.
|
|
0
|
|
|
|
Reply
|
ben.usenet (6515)
|
10/24/2009 1:22:38 PM
|
|
This version still has one conditional jump too many in the code path.
( GCC needs the temp, because it does not appear to recognize the CSE)
************************/
int median3(int a,int b,int c)
{
/* register */ unsigned tmp;
/* 2.0 1.1 0.2 0 */
tmp = ( (0x2148U >> ((((a>b)<<1)+((b>c)<<2)+((c>a)<<3)))) &3);
return tmp & 2 ? c : tmp ? b : a;
}
/***********************
AvK
|
|
0
|
|
|
|
Reply
|
root32 (398)
|
10/24/2009 2:17:24 PM
|
|
On 2009-10-24, Phil Carmody <thefatphil_demunged@yahoo.co.uk> wrote:
> printf("I see %u ship%s.\n", nships, "s"+(nships==1));
Oh, that's pretty. I'm not sure I like it, but it's pretty.
-s
--
Copyright 2009, all wrongs reversed. Peter Seebach / usenet-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
|
|
0
|
|
|
|
Reply
|
usenet-nospam (2199)
|
10/24/2009 3:25:24 PM
|
|
Phil Carmody <thefatphil_demunged@yahoo.co.uk> writes:
> printf("I see %u ship%s.\n", nships, "s"+(nships==1));
This sort of thing is always clever, but it falls down badly when
you need to internationalize your code.
--
Ben Pfaff
http://benpfaff.org
|
|
0
|
|
|
|
Reply
|
blp (3953)
|
10/24/2009 3:35:55 PM
|
|
"user923005" <dcorbit@connx.com> ha scritto nel messaggio
news:c70d29fe-48dc-44b8-9995-95dcf59df129@s21g2000prm.googlegroups.com...
>/*
>Surprising to me, the switch ran 4x slower than the simple if() tests.
>It appears that the missed branch predictions are killer.
>I guess that profile guided optimization will help your routine
>quite a bit if the data has some particular pattern.
>*/
>typedef int e_type;
>e_type median3(e_type a, e_type b, e_type c)
>{
> return (a < b) ? ((b < c) ? b : ((a < c) ? c : a)) : ((a < c) ?
>a : ((b < c) ? c : b));
>}
what about
e_type medianr(e_type a, e_type b, e_type c)
{e_type r;
if(a>c) {r=a, a=c, c=r;}
if(a>b) {r=a, a=b, b=r;}
if(c<b) {r=c, c=b, b=r;}
return b;
}
or
-------------------
section _DATA use32 public class=DATA
global _medianrAsm
section _TEXT use32 public class=CODE
; medianrAsm(r, a, c)
; 0ra, 4P1, 8P2, 12P3
_medianrAsm:
mov edx, dword[esp+ 4]
mov eax, dword[esp+ 8]
mov ecx, dword[esp+ 12]
cmp edx, ecx
jle .1
xchg edx, ecx
..1: cmp edx, eax
jle .2
xchg eax, edx
..2: cmp ecx, eax
jge .3
xchg eax, ecx
..3:
ret
-------------------------
|
|
0
|
|
|
|
Reply
|
io_x
|
10/24/2009 4:23:41 PM
|
|
In <slrnhe673l.sgj.usenet-nospam@guild.seebs.net>, Seebs wrote:
> On 2009-10-24, Phil Carmody <thefatphil_demunged@yahoo.co.uk> wrote:
>> printf("I see %u ship%s.\n", nships, "s"+(nships==1));
>
> Oh, that's pretty. I'm not sure I like it, but it's pretty.
It's very 90s. (Sorry, Phil, but it is.)
So is:
printf("I see %u ship%s.\n", nships, &(nships==1)["s"]);
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
|
|
0
|
|
|
|
Reply
|
rjh (10789)
|
10/24/2009 5:48:17 PM
|
|
Phil Carmody <thefatphil_demunged@yahoo.co.uk> writes:
> Keith Thompson <kst-u@mib.org> writes:
>> James Dow Allen <jdallen2000@yahoo.com> writes:
>>> On Oct 22, 1:51 pm, Keith Thompson <ks...@mib.org> wrote:
>>>> Rule of thumb: If a ?: operator can be written equivalently as an
>>>> if-else statement, write it as an if-else statement (unless it's
>>>> part of a macro definition).
>>>
>>> I think we'd all agree that "cutesy" shortcuts to achieve a
>>> false keystroke economy are wrong, but this statement goes much
>>> too far. It seems to assume that "if else" is more readable
>>> than "? :" but that should *not* be the case for a C programmer.
>>
>> I was referring specifically to cases where a ?: operator appears at
>> the top level of a statement expression, and the second and third
>> operands' results are discarded. For example:
>>
>> condition ? puts("A message") : puts("Another message");
>>
>> In my opinion, using ?: here is just silly; it's better written as:
>>
>> if (condition) {
>> puts("A message");
>> }
>> else {
>> puts("Another message");
>> }
>
> Better written as:
>
> puts(condition ? "A message" : "Another message");
Ok, I picked a poor example.
What I object to is code that uses ?: rather than if-else for no good
reason. Avoiding writing the same code twice (the puts() call) can be
a good reason. So can writing code for a function-like macro. Saving
keystrokes is not.
[...]
>> (But tabs? Spaces only, please.)
>
> A coding standard which is 100% strict about how wide a tab is
> may also approve or demand the use of tabs.
In my experience, nothing works better than a complete ban on tabs in
source code. There are too many different opinions on how wide a
tabstop should be (which is, or should be, a different question than
what an indentation level should be).
<http://www.emacswiki.org/emacs-en/TabsvsSpaces>
> I don't personally care - I press 'tab' in emacs, and it makes
> the code conform to the coding standard in effect at the time.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
|
|
0
|
|
|
|
Reply
|
kst-u (21469)
|
10/24/2009 8:01:23 PM
|
|
On Thu, 22 Oct 2009 14:14:49 -0700, Keith Thompson wrote:
> I do sometimes write fairly long *linear* chains of conditional
> operators. For example:
>
> printf("x = %d = %s\n",
> x,
> x == SOME_CONSTANT ? "SOME_CONSTANT" :
> x == ANOTHER_CONSTANT ? "ANOTHER_CONSTANT" :
> x == YET_ANOTHER_CONSTANT ? "YET_ANOTHER_CONSTANT" :
> /* ... */
> "???");
I sometimes find chains like the above to be much
clearer than some long unwieldy if-else ladder.
Here's another example, from a few years back:
(offLmod == offRmod ? ror_d0 :
minlen <= BITS ? ror_short :
offLmod < offRmod ? ror_long_dn :
ror_long_up )
(bsL->data+offLdiv, bsR->data+offRdiv, offLmod, offRmod, minlen);
I realize now that maybe it should've been:
void (*fptr)(/* args */) =
(offLmod == offRmod ? ror_d0 :
minlen <= BITS ? ror_short :
offLmod < offRmod ? ror_long_dn :
ror_long_up);
(*fptr) (bsL->data+offLdiv, bsR->data+offRdiv, offLmod, offRmod,
minlen);
I think both are very readable and maintainable because
of the way the conditions and results are listed in
separate columns, and because the function arguments
only have to be spelled out once.
/Nisse
|
|
0
|
|
|
|
Reply
|
news.NOSPAM.wbarspjz (4)
|
10/24/2009 11:03:05 PM
|
|
In <JILEm.12398$U5.179864@newsb.telia.net>, Nisse Engstr�m wrote:
<snip>
> Here's another example, from a few years back:
>
> (offLmod == offRmod ? ror_d0 :
> minlen <= BITS ? ror_short :
> offLmod < offRmod ? ror_long_dn :
> ror_long_up )
> (bsL->data+offLdiv, bsR->data+offRdiv, offLmod, offRmod,
> minlen);
>
> I realize now that maybe it should've been:
>
> void (*fptr)(/* args */) =
> (offLmod == offRmod ? ror_d0 :
> minlen <= BITS ? ror_short :
> offLmod < offRmod ? ror_long_dn :
> ror_long_up);
Better still, wrap up the complexity in a function:
typedef void ror_function_type( /* args */ );
/* ... */
ror_function_type *p = get_ror_function(offLmod, offRmod, etc!);
(*p)(args);
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
|
|
0
|
|
|
|
Reply
|
rjh (10789)
|
10/25/2009 1:07:49 AM
|
|
"io_x" <a@b.c.invalid> ha scritto nel messaggio
news:4ae32865$0$1117$4fafbaef@reader1.news.tin.it...
>
> "user923005" <dcorbit@connx.com> ha scritto nel messaggio
> news:c70d29fe-48dc-44b8-9995-95dcf59df129@s21g2000prm.googlegroups.com...
>>/*
>>Surprising to me, the switch ran 4x slower than the simple if() tests.
>
>>It appears that the missed branch predictions are killer.
>>I guess that profile guided optimization will help your routine
>>quite a bit if the data has some particular pattern.
>>*/
>
>>typedef int e_type;
>
>>e_type median3(e_type a, e_type b, e_type c)
>>{
>> return (a < b) ? ((b < c) ? b : ((a < c) ? c : a)) : ((a < c) ?
>>a : ((b < c) ? c : b));
>>}
>
>
> what about
> e_type medianr(e_type a, e_type b, e_type c)
> {e_type r;
> if(a>c) {r=a, a=c, c=r;}
> if(a>b) {r=a, a=b, b=r;}
> if(c<b) {r=c, c=b, b=r;}
> return b;
> }
>
> or
> -------------------
> section _DATA use32 public class=DATA
> global _medianrAsm
> section _TEXT use32 public class=CODE
>
> ; medianrAsm(r, a, c)
> ; 0ra, 4P1, 8P2, 12P3
> _medianrAsm:
> mov edx, dword[esp+ 4]
> mov eax, dword[esp+ 8]
> mov ecx, dword[esp+ 12]
> cmp edx, ecx
> jle .1
> xchg edx, ecx
> .1: cmp edx, eax
> jle .2
> xchg eax, edx
> .2: cmp ecx, eax
> jge .3
> xchg eax, ecx
> .3:
> ret
> -------------------------
with
-------
section _DATA use32 public class=DATA
global _medianrAsm
section _TEXT use32 public class=CODE
; a r c
; 0 1 2 -
; medianrAsm(r, a, c)
; 0ra, 4P1, 8P2, 12P3
align 8
_medianrAsm:
mov eax, dword[esp+ 4]
mov edx, dword[esp+ 8]
mov ecx, dword[esp+ 12]
cmp eax, ecx
jle .1
xchg eax, ecx
; a<=c 0<=2
..1: cmp edx, eax
jg .2
ret ; r<=a<=c 1<=0<=2
..2: cmp ecx, edx
jg .3
mov eax, ecx
ret ; a<=c<=r 0<=2<=1
..3: mov eax, edx ; a<=r<=c
ret
---
Prova median3
m=843962432 Result: 29.000000
--------------
Prova median3a
m=843962432 Result: 28.000000
--------------
Prova median3b
m=843962432 Result: 43.000000
--------------
Prova medianr
m=843962432 Result: 29.000000
--------------
Prova medianrAsm
m=843962432 Result: 28.000000
--------------
they are all of the same speed but
median3b
seems slower
------------------------
#define P printf
/*
Surprising to me, the switch ran 4x slower than the simple if() tests.
It appears that the missed branch predictions are killer.
I guess that profile guided optimization will help your routine
quite a bit if the data has some particular pattern.
*/
typedef int e_type;
e_type median3(e_type a, e_type b, e_type c)
{
return (a < b) ? ((b < c) ? b : ((a < c) ? c : a)) : ((a < c) ?
a : ((b < c) ? c : b));
}
e_type medianrAsm(e_type a, e_type b, e_type c);
e_type medianr(e_type a, e_type b, e_type c)
{e_type r;
if(a>c) {r=a; a=c; c=r;}
/* a<c */
if(a>b) return a;
if(c<b) return c; /* a<c<b */
return b;
}
e_type median3a(e_type a, e_type b, e_type c)
{
if (a < b) {
if (b < c)
return b; /* a b c */
if (c < a)
return a; /* c a b */
return c; /* a c b */
} else {
if (a < c)
return a; /* b a c */
if (c < b)
return b; /* c b a */
return c; /* b c a */
}
}
e_type median3b(e_type a, e_type b, e_type c)
{
switch ((a > b) + ((b > c) << 1) + ((c > a) << 2)) {
case 0:
return a;
case 1:
return c;
case 2:
return a;
case 3:
return b;
case 4:
return b;
case 5:
return a;
case 6:
default:
return c;
}
}
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
double prova(e_type (*f)(e_type, e_type, e_type))
{time_t t1, t2;
double d;
e_type i, j, k, m=0, m1, m2;
t1=time(0);
for(i=0; i<1000; i++)
for(j=0; j<1000; j++)
for (k=0; k<3000; k++)
{m1=i^j; m2=i^k;
m += f(m1, i, m2);
}
t2=time(0);
d=difftime(t2, t1);
P("m=%u ", (unsigned) m);
return d;
}
double prova1(e_type (*f)(e_type, e_type, e_type))
{time_t t1, t2;
double d;
e_type i, j, k, m=0, kk;
t1=time(0);
for(kk=0; kk<300000000 ; ++kk)
{i=rand(); j=rand(); k=rand();
m+=f(i, j, k);
}
t2=time(0);
d=difftime(t2, t1);
P("m=%u ", (unsigned) m);
return d;
}
int main(void)
{ double h;
e_type i,
j,
k,
m,
m2,
m3;
for (i = 0; i < 300; i++)
for (j = 0; j < 300; j++)
for (k = 0; k < 300; k++) {
m = median3(i, j, k);
m2 = medianr(i, j, k);
m3 = medianrAsm(i, j, k);
if (m3 != m)
{printf("Disagreement of %d verses %d\n", m3, m);
printf("median of %d %d %d is %d\n", i, j, k, m3);
return 0;
}
if (m2 != m)
{printf("Disagreement of %d verses %d\n", m2, m);
printf("median of %d %d %d is %d\n", i, j, k, m2);
return 0;
}
}
P("Prova median3\n");
h=prova(median3);
P("Result: %f\n", h);
P("--------------\n");
P("Prova median3a\n");
h=prova(median3a);
P("Result: %f\n", h);
P("--------------\n");
P("Prova median3b\n");
h=prova(median3b);
P("Result: %f\n", h);
P("--------------\n");
P("Prova medianr\n");
h=prova(medianr);
P("Result: %f\n", h);
P("--------------\n");
P("Prova medianrAsm\n");
h=prova(medianrAsm);
P("Result: %f\n", h);
P("--------------\n");
return 0;
}
|
|
0
|
|
|
|
Reply
|
io_x
|
10/25/2009 6:35:13 AM
|
|
On Sun, 25 Oct 2009 01:07:49 +0000, Richard Heathfield wrote:
> In <JILEm.12398$U5.179864@newsb.telia.net>, Nisse Engström wrote:
>
>> void (*fptr)(/* args */) =
>> (offLmod == offRmod ? ror_d0 :
>> minlen <= BITS ? ror_short :
>> offLmod < offRmod ? ror_long_dn :
>> ror_long_up);
>
> Better still, wrap up the complexity in a function:
>
> typedef void ror_function_type( /* args */ );
>
> /* ... */
>
> ror_function_type *p = get_ror_function(offLmod, offRmod, etc!);
>
> (*p)(args);
A typedef for the function declaration is definitely
a win.
I think that the control logic (in this case where
it is used only once) is a little to short to be moved
away into a separate function, but I'll concede that
you have /at least/ half a point.
On the other hand, the exact same logic appears in
several files, but with a different set of functions.
That may yet give cause for some creativity.
/Nisse
|
|
0
|
|
|
|
Reply
|
news.NOSPAM.wbarspjz (4)
|
10/25/2009 7:06:53 AM
|
|
On Oct 24, 11:35=A0pm, Ben Pfaff <b...@cs.stanford.edu> wrote:
> Phil Carmody <thefatphil_demun...@yahoo.co.uk> writes:
> > printf("I see %u ship%s.\n", nships, "s"+(nships=3D=3D1));
>
> This sort of thing is always clever, but it falls down badly when
> you need to internationalize your code.
So would the equivalent if else. I am aware that in practical
internationalization, programmers are directed to use "resources" of
strings with the "right" translations normally prepared by technical
writers and translators. Correspondingly, they are discouraged in my
experience from writing code like the above which seems and is rather
clever...but ties the program to English, thereby increasing le
dominance Anglo-Saxonne over tout le monde in fashion neo-colonialiste
alors peut etre Fasciste.
My own theory is that programmers should be widely and deeply cultured
with the resulting awareness of when they are building in such a
dependency. The problem being that most programmers are what the
Russians would call ne kulterni and what Indian chaps call jungly.
It is a wicked world. When I first read, in Frederick Brooks' The
Mythical Man Month, of the concept of The Chief Programmer, I saw
Hor. Where my Lord?
Ham. In my Minde's Eye, Horatio.
Klaatu from The Day the Earth Stood Still, in his cool spaceship in a
business suit like my father
Ham. I thinke I see my Father
But then I woke up and looked about me. The head of my company,
despite his reputation as being a "great" programmer (he'd developed
credit reporting systems which now mess up our lives) was to my father
Hamlet's "satyr" to "Hyperion", a man who looked like a frog with no
table manners or any other manners worthy of note.
I could see that the position of Chief Programmer would always go
unfilled. But a Chief Programmer would know as much about
internationalization as does Bjarne Stroustrup, without having
Stroustrup's many illusions.
One peruses Zizek and Lacan because of this paradox. A society which
worships power and control takes it away from each one of its members.
> --
> Ben Pfaffhttp://benpfaff.org
|
|
0
|
|
|
|
Reply
|
spinoza1111 (3250)
|
10/25/2009 8:32:43 AM
|
|
On Oct 24, 11:25 pm, Seebs <usenet-nos...@seebs.net> wrote:
> On 2009-10-24, Phil Carmody <thefatphil_demun...@yahoo.co.uk> wrote:
>
> > printf("I see %u ship%s.\n", nships, "s"+(nships=3D=3D1));
>
> Oh, that's pretty. I'm not sure I like it, but it's pretty.
Away with this Bauble, as Cromwell said of the Parliamentary mace. It
is an IDIOM. It's like saying in Cantonese "lok gau si" or "falling
dog poo" (=B8=A8=AA=AF=AB=CB: the Cantonese idiom for "raining cats and dog=
s"). It is
falling C poo.
Furthermore I do not see why this false cleverness gets even qualified
praise when people here defend nonsense such as
a=3D*b; // Not even needed in C sharp
or
return x>0 ? 1 : -1; // "Signum" my ass
>
> -s
> --
> Copyright 2009, all wrongs reversed. Peter Seebach / usenet-nos...@seebs=
..nethttp://www.seebs.net/log/<-- lawsuits, religion, and funny pictureshttp=
://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
|
|
0
|
|
|
|
Reply
|
spinoza1111 (3250)
|
10/25/2009 8:39:43 AM
|
|
On Oct 25, 4:32=C2=A0pm, spinoza1111 <spinoza1...@yahoo.com> wrote:
> On Oct 24, 11:35=C2=A0pm, Ben Pfaff <b...@cs.stanford.edu> wrote:
>
> > Phil Carmody <thefatphil_demun...@yahoo.co.uk> writes:
> > > printf("I see %u ship%s.\n", nships, "s"+(nships=3D=3D1));
>
> > This sort of thing is always clever, but it falls down badly when
> > you need to internationalize your code.
>
> So would the equivalent if else. I am aware that in practical
> internationalization, programmers are directed to use "resources" of
> strings with the "right" translations normally prepared by technical
> writers and translators. Correspondingly, they are discouraged in my
> experience from writing code like the above which seems and is rather
> clever...but ties the program to English, thereby increasing le
> dominance Anglo-Saxonne over tout le monde in fashion neo-colonialiste
> alors peut etre Fasciste.
>
> My own theory is that programmers should be widely and deeply cultured
> with the resulting awareness of when they are building in such a
> dependency. The problem being that most programmers are what the
> Russians would call ne kulterni and what Indian chaps call jungly.
>
> It is a wicked world. When I first read, in Frederick Brooks' The
> Mythical Man Month, of the concept of The Chief Programmer, I saw
>
> Hor. Where my Lord?
> Ham. In my Minde's Eye, Horatio.
>
> Klaatu from The Day the Earth Stood Still, in his cool spaceship in a
> business suit like my father
>
> Ham. I thinke I see my Father
>
> But then I woke up and looked about me. The head of my company,
> despite his reputation as being a "great" programmer (he'd developed
> credit reporting systems which now mess up our lives) was to my father
> Hamlet's "satyr" to "Hyperion", a man who looked like a frog with no
> table manners or any other manners worthy of note.
>
> I could see that the position of Chief Programmer would always go
> unfilled. But a Chief Programmer would know as much about
> internationalization as does Bjarne Stroustrup, without having
> Stroustrup's many illusions.
>
> One peruses Zizek and Lacan because of this paradox. A society which
> worships power and control takes it away from each one of its members.
>
>
>
> > --
> > Ben Pfaffhttp://benpfaff.org- Hide quoted text -
>
> - Show quoted text -
That is, Babbage was prescient if also a horse's ass in naming his
book Life of a Philosopher: for I've always believed that the only
people qualified to be programmers would be philosophy majors.
Let the =E8=90=BD=E7=8B=97=E5=B1=8E begin...
|
|
0
|
|
|
|
Reply
|
spinoza1111 (3250)
|
10/25/2009 8:43:05 AM
|
|
Seebs <usenet-nospam@seebs.net> writes:
> On 2009-10-24, Phil Carmody <thefatphil_demunged@yahoo.co.uk> wrote:
>> printf("I see %u ship%s.\n", nships, "s"+(nships==1));
>
> Oh, that's pretty. I'm not sure I like it, but it's pretty.
I'm surprised. I would have expected a response more like:
"Oh, that's ugly. I'm pretty sure I like it, but it's ugly."
Phil
--
Any true emperor never needs to wear clothes. -- Devany on r.a.s.f1
|
|
0
|
|
|
|
Reply
|
thefatphil_demunged (1558)
|
10/25/2009 11:02:10 AM
|
|
Richard Heathfield <rjh@see.sig.invalid> writes:
> In <slrnhe673l.sgj.usenet-nospam@guild.seebs.net>, Seebs wrote:
>
>> On 2009-10-24, Phil Carmody <thefatphil_demunged@yahoo.co.uk> wrote:
>>> printf("I see %u ship%s.\n", nships, "s"+(nships==1));
>>
>> Oh, that's pretty. I'm not sure I like it, but it's pretty.
>
> It's very 90s. (Sorry, Phil, but it is.)
I think I first used its BASIC equivalent in about 1982 on my ZX-81,
when coding 99-bottles. So you've flattered me enormously by calling
it 90s!
> So is:
>
> printf("I see %u ship%s.\n", nships, &(nships==1)["s"]);
That's IOCCC-ies.
Phil
--
Any true emperor never needs to wear clothes. -- Devany on r.a.s.f1
|
|
0
|
|
|
|
Reply
|
thefatphil_demunged (1558)
|
10/25/2009 11:04:39 AM
|
|
Ben Pfaff <blp@cs.stanford.edu> writes:
> Phil Carmody <thefatphil_demunged@yahoo.co.uk> writes:
>
>> printf("I see %u ship%s.\n", nships, "s"+(nships==1));
>
> This sort of thing is always clever, but it falls down badly when
> you need to internationalize your code.
But there it falls down on the 9th character, not at the 38th.
Phil
--
Any true emperor never needs to wear clothes. -- Devany on r.a.s.f1
|
|
0
|
|
|
|
Reply
|
thefatphil_demunged (1558)
|
10/25/2009 11:06:26 AM
|
|
Ben Pfaff <blp@cs.stanford.edu> wrote:
> Phil Carmody <thefatphil_demunged@yahoo.co.uk> writes:
>
> > printf("I see %u ship%s.\n", nships, "s"+(nships==1));
>
> This sort of thing is always clever, but it falls down badly when
> you need to internationalize your code.
True, but when you need that, there is no single printf() call that
prints that sentence reliably. Even
if (nships==1)
printf(inter("I see 1 ship.\n"));
else
printf(inter("I see %u ships.\n"), nships);
while a lot more internationalisable, is not enough to guarantee
portability to all languages.
Richard
(Hint: two.)
|
|
0
|
|
|
|
Reply
|
raltbos (821)
|
10/25/2009 4:34:42 PM
|
|
Phil Carmody <thefatphil_demunged@yahoo.co.uk> wrote:
> Keith Thompson <kst-u@mib.org> writes:
> > (But tabs? Spaces only, please.)
>
> A coding standard which is 100% strict about how wide a tab is
> may also approve or demand the use of tabs.
If so, such a coding standard will only work in-house, on a strictly
controlled set of hardware. It's possible, but it's harder work than a
coding standard should want to do.
Richard
|
|
0
|
|
|
|
Reply
|
raltbos (821)
|
10/25/2009 4:34:43 PM
|
|
On Oct 25, 4:04=A0am, Phil Carmody <thefatphil_demun...@yahoo.co.uk>
wrote:
> Richard Heathfield <r...@see.sig.invalid> writes:
> > In <slrnhe673l.sgj.usenet-nos...@guild.seebs.net>, Seebs wrote:
>
> >> On 2009-10-24, Phil Carmody <thefatphil_demun...@yahoo.co.uk> wrote:
> >>> printf("I see %u ship%s.\n", nships, "s"+(nships=3D=3D1));
>
> >> Oh, that's pretty. =A0I'm not sure I like it, but it's pretty.
>
> > It's very 90s. (Sorry, Phil, but it is.)
>
> I think I first used its BASIC equivalent in about 1982 on my ZX-81,
> when coding 99-bottles. So you've flattered me enormously by calling
> it 90s!
>
> > So is:
>
> > printf("I see %u ship%s.\n", nships, &(nships=3D=3D1)["s"]);
>
> That's IOCCC-ies.
>
> Phil
Nah, this is IOCCCness...
printf("I see %u ship%s.\n", nships, "s"+!~-nships);
Using all three types of negation in one expression is priceless, the
C equivalent of Euler's idenity.
(Assuming 2's complement arithmetic, of course.)
Steven
|
|
0
|
|
|
|
Reply
|
svfuerst (24)
|
10/25/2009 6:25:35 PM
|
|
"Richard Bos" <raltbos@xs4all.nl> wrote in message news:
> Ben Pfaff <blp@cs.stanford.edu> wrote:
>
>> Phil Carmody <thefatphil_demunged@yahoo.co.uk> writes:
>>
>> > printf("I see %u ship%s.\n", nships, "s"+(nships==1));
>>
>> This sort of thing is always clever, but it falls down badly when
>> you need to internationalize your code.
>
> True, but when you need that, there is no single printf() call that
> prints that sentence reliably. Even
>
> if (nships==1)
> printf(inter("I see 1 ship.\n"));
> else
> printf(inter("I see %u ships.\n"), nships);
>
> while a lot more internationalisable, is not enough to guarantee
> portability to all languages.
>
Like Arabic, for example. It has a dual. Also the language the rabbits speak
in Watership Down. It has a special form for all numbers over four.
|
|
0
|
|
|
|
Reply
|
regniztar (3128)
|
10/25/2009 7:08:23 PM
|
|
"Gareth Owen" <gwowen@gmail.com> wrote in message
>
> Summary: Unless you know the context, you can't say whether either
> code fragment is buggy or not.
>
I got bittten with this once. If a construct shows defined behaviour you can
always claim it is th desired behaviour. Even calling fgets() and throwing
away the newline (if the purpose of the program is to throw away newlines).
|
|
0
|
|
|
|
Reply
|
regniztar (3128)
|
10/25/2009 7:14:44 PM
|
|
raltbos@xs4all.nl (Richard Bos) writes:
> Phil Carmody <thefatphil_demunged@yahoo.co.uk> wrote:
>
>> Keith Thompson <kst-u@mib.org> writes:
>> > (But tabs? Spaces only, please.)
>>
>> A coding standard which is 100% strict about how wide a tab is
>> may also approve or demand the use of tabs.
>
> If so, such a coding standard will only work in-house, on a strictly
> controlled set of hardware. It's possible, but it's harder work than a
> coding standard should want to do.
False. Linux's coding standard works across hundreds of companies
and thousands of individuals, who I'm sure use a wider selection
of hardware than found amongst the proponents of any other coding
standard. Yes, it's hard work to police, but there are thousands
of people, and hundreds of robots, policing it.
Phil
--
Any true emperor never needs to wear clothes. -- Devany on r.a.s.f1
|
|
0
|
|
|
|
Reply
|
thefatphil_demunged (1558)
|
10/25/2009 9:19:52 PM
|
|
In <2KKdnYav5oMAPnnXnZ2dnUVZ8i2dnZ2d@bt.com>, Malcolm McLean wrote:
> "Gareth Owen" <gwowen@gmail.com> wrote in message
>>
>> Summary: Unless you know the context, you can't say whether either
>> code fragment is buggy or not.
>>
> I got bittten with this once. If a construct shows defined behaviour
> you can always claim it is th desired behaviour. Even calling
> fgets() and throwing away the newline (if the purpose of the program
> is to throw away newlines).
If the purpose of the program is to throw away newlines, why on earth
would you call fgets()?
#include <stdio.h>
int main(void)
{
int ch;
while((ch = getchar()) != EOF) if(ch != '\n') putchar(ch);
return 0;
}
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
|
|
0
|
|
|
|
Reply
|
rjh (10789)
|
10/26/2009 6:29:15 AM
|
|
Keith Thompson <kst-u@mib.org> writes:
> James Dow Allen <jdallen2000@yahoo.com> writes:
>> On Oct 22, 1:51 pm, Keith Thompson <ks...@mib.org> wrote:
>>> Rule of thumb: If a ?: operator can be written equivalently as an
>>> if-else statement, write it as an if-else statement (unless it's
>>> part of a macro definition).
>>
>> I think we'd all agree that "cutesy" shortcuts to achieve a
>> false keystroke economy are wrong, but this statement goes much
>> too far. It seems to assume that "if else" is more readable
>> than "? :" but that should *not* be the case for a C programmer.
>
> I was referring specifically to cases where a ?: operator appears at
> the top level of a statement expression, and the second and third
> operands' results are discarded. [snip..]
>
>> I often string together ?, : and/or && and || into an involved
>> expression, and add newlines and tabs to make it easy to read.
>> IMHO the if/else equivalent would be harder to read because of
>> all the "if/else" clutter.
>
> Can you give an example? [snip]
I might use ?: at the top level if it helped chunkify the code in
a useful way. I find it helps a lot to cluster certain portions
of an algorithm and let others space out more. Here are several
versions of a code fragment for doing some sort of binary search:
low = 0;
high = n;
while (low+1 < high)
{
int m = low + (high-low)/2;
if (ordering(a[m],v) < 1)
{
low = m;
}
else
{
high = m;
}
}
low = 0;
high = n;
while (low+1 < high) {
int m = low + (high-low)/2;
if (ordering(a[m],v) < 1) {
low = m;
} else {
high = m;
}
}
low = 0;
high = n;
while (low+1 < high) {
int m = low + (high-low)/2;
if (ordering(a[m],v) < 1) low = m;
else high = m;
}
low = 0, high = n;
while (low+1 < high) {
int m = low + (high-low)/2;
ordering(a[m],v) < 1 ? (low = m) : (high = m);
}
The last version best expresses how I conceptualize a binary
search algorithm. Written in words, this might be
establish loop invariant for entire array range
WHILE interval has more than one element
compute interval midpoint
restore loop invariant by choosing appropriate sub-interval
END
I don't mean to say that good conceptual match is the only
factor in making coding decisions; obviously there are
many factors. Other things being equal, however, I would
rather see code written in a way that chunks of code on
the page match up to the conceptual chunks that make up
the underlying algorithm. The particular use of ?: does
that rather well in this example (IMO, of course).
|
|
0
|
|
|
|
Reply
|
txr1 (1213)
|
10/26/2009 6:45:11 AM
|
|
Gareth Owen <gwowen@gmail.com> writes:
> Keith Thompson <kst-u@mib.org> writes:
>
>> Can you give an example? If it doesn't meet the criteria I mentioned
>> above, so that the transformation from ?: to if-else is absolutely
>> trivial, I probably wouldn't object. I don't find "if" and "else" to
>> be clutter; they're just part of the code.
>
> I'm not the original poster but this did remind me of something.
> About 5 years ago there was a lengthy thread on c.l.c++ about whether
> designing functions to be single-entry-single-exit was still a
> worthwhile goal (since exceptions were necessarily a hidden other-exit
> but I digress)...
>
> Anyway, some of the strongest proponents of one-return-statement per
> function would indulge this stylistic fetish by refactoring this:
>
> /* ... excerpt from Game Of Life Code */
> if(live_neighbours == 3) return true;
> if(live_neighbours == 2) return data[x][y];
> return false;
>
> into
>
> /* ... excerpt from Game Of Life Code */
> return live_neighbours == 3 ? true
> : live_neighbours == 2 ? data[x][y]
> : false;
>
> I don't like the latter because it requires me to either have the
> precedence rules at my fingertips, or (more likely) LISP it up until
> it said
>
> return (live_neighbours == 3 ? true :
> (live_neighbours == 2 ? data[x][y] : false));
return live_neighbors == 3 || live_neighbors == 2 && data[x][y];
Simple, direct expression of the condition for life.
|
|
0
|
|
|
|
Reply
|
txr1 (1213)
|
10/26/2009 6:47:30 AM
|
|
Richard Heathfield <rjh@see.sig.invalid> writes:
> In
> <13a223a9-c307-4bcd-95a7-ef46b6fada62@g22g2000prf.googlegroups.com>,
> James Dow Allen wrote:
>
> <snip>
>
>> I was happy to see in this thread that I'm not the only who
>> finds it virtuous to conserve vertical space. Evidently
>> Mr. Heathfield is not in our select company! :-)
>
> Right. I've found that I can afford millions of lines of vertical
> space. It's much cheaper than is commonly believed.
>
>> Richard, are you one of these people with 20-10 vision who
>> view code in the smallest font available?
>
> No, if anything I use a slightly oversized font. But I try to keep my
> functions relatively short, [snip]
Hmmm. I think your relatives must be a lot taller than mine
are.
|
|
0
|
|
|
|
Reply
|
txr1 (1213)
|
10/26/2009 6:51:41 AM
|
|
Gareth Owen <gwowen@gmail.com> writes:
> Richard <rgrdev_@gmail.com> writes:
>
>> [... on expressions like 'a = b ? c : d' ...]
>
> I know its straightforward. It's still clunky and unclear. If you
> really want that interpretation, but some brackets in there. Program
> as you if expect other people to read your code. Express your intent,
> and don't expect everyone to enjoy C's more pointless idioms as much
> as you do. [snip elaboration]
The ?: operator is not some obscure corner of C, nor does using
it automatically qualify as an idiom. If someone who claims to
know C can't both read and write C code that has an occasional
use of ?:, he or she isn't worthy of being called a programmer.
Yes, I learned FORTRAN as my first language; 360 assembly as
my second. I know there are people who yearn for "the good
old days" and would be just as happy being stuck there forever.
More sensible people want to move past that.
|
|
0
|
|
|
|
Reply
|
txr1 (1213)
|
10/26/2009 7:06:32 AM
|
|
"io_x" <a@b.c.invalid> writes:
> "user923005" <dcorbit@connx.com> ha scritto nel messaggio
>[snip performance questions]
>
>>typedef int e_type;
>
>>e_type median3(e_type a, e_type b, e_type c)
>>{
>> return (a < b) ? ((b < c) ? b : ((a < c) ? c : a)) : ((a < c) ?
>>a : ((b < c) ? c : b));
>>}
>
>
> what about
> e_type medianr(e_type a, e_type b, e_type c)
> {e_type r;
> if(a>c) {r=a, a=c, c=r;}
> if(a>b) {r=a, a=b, b=r;}
> if(c<b) {r=c, c=b, b=r;}
> return b;
> }
In all these different variations of median, it's suprising that
no one has emphasized obviousness of correctness. For example,
...
#define CHECK(a,b,c) do if ((a)<=(b) && (b)<=(c)) return (b); while(0)
CHECK(a,b,c);
CHECK(a,c,b);
CHECK(b,a,c);
CHECK(b,c,a);
CHECK(c,a,b);
CHECK(c,b,a);
assert(0);
return 0;
#undef CHECK
or instead using the return form
#define CHECK(a,b,c) ((a)<=(b) && (b)<=(c)) ? (b)
return CHECK(a,b,c)
: CHECK(a,c,b)
: CHECK(b,a,c)
: CHECK(b,c,a)
: CHECK(c,a,b)
: CHECK(c,b,a)
: (assert(0), 0);
#undef CHECK
In either of these it's easy to tell at a glance that all
cases are tested and that the appropriate value is returned
in all cases.
|
|
0
|
|
|
|
Reply
|
txr1 (1213)
|
10/26/2009 7:27:09 AM
|
|
Tim Rentsch <txr@alumni.caltech.edu> writes:
> The ?: operator is not some obscure corner of C, nor does using it
> automatically qualify as an idiom. If someone who claims to know C
> can't both read and write C code that has an occasional use of ?:,
> he or she isn't worthy of being called a programmer.
Can you lay off "the isn't worthy of being called a programmer"
schtick. It's incredibly patronising.
I've never argued about programmers who "can" or "can't".
Comprehension is not a binary "can comprehend" and "can't comprehend".
I can comprehend the writing of JK Rowling and James Joyce[0], but one
of them is lot less work.[1] But, I'd like to think that good
programmers would strive to be more like the former than the latter.
Good authors, maybe not.
I can read comprehend ?:, and in simple expressions it can be much
more eloquent. There are places where the brevity of ?: gives a
program extra clarity for the reader. But when the expressions are
complex that clarity is lost, comprehension becomes much harder work
and the only gain is a little less typing. That's a poor tradeoff, if
your code is ever to be maintained by people less eloquent in C than
yourself.
My point is merely this. If I use ?: in complex expressions, what is
the benefit and what do I gain?
[0] Well, sort of. I'm only human.
[1] And if consider it a good thing that your code could be described
as "Joycean", go right ahead and continue using tortuous
constructs.
|
|
0
|
|
|
|
Reply
|
gwowen (518)
|
10/26/2009 7:46:17 AM
|
|
Nisse Engström <news.NOSPAM.wbarspjz@luden.se> writes:
> On Thu, 22 Oct 2009 14:14:49 -0700, Keith Thompson wrote:
>
>> I do sometimes write fairly long *linear* chains of conditional
>> operators. For example:
>>
>> printf("x = %d = %s\n",
>> x,
>> x == SOME_CONSTANT ? "SOME_CONSTANT" :
>> x == ANOTHER_CONSTANT ? "ANOTHER_CONSTANT" :
>> x == YET_ANOTHER_CONSTANT ? "YET_ANOTHER_CONSTANT" :
>> /* ... */
>> "???");
>
> I sometimes find chains like the above to be much
> clearer than some long unwieldy if-else ladder.
> Here's another example, from a few years back:
>
> (offLmod == offRmod ? ror_d0 :
> minlen <= BITS ? ror_short :
> offLmod < offRmod ? ror_long_dn :
> ror_long_up )
> (bsL->data+offLdiv, bsR->data+offRdiv, offLmod, offRmod, minlen);
>
> I realize now that maybe it should've been:
>
> void (*fptr)(/* args */) =
> (offLmod == offRmod ? ror_d0 :
> minlen <= BITS ? ror_short :
> offLmod < offRmod ? ror_long_dn :
> ror_long_up);
>
> (*fptr) (bsL->data+offLdiv, bsR->data+offRdiv, offLmod, offRmod,
> minlen);
>
> I think both are very readable and maintainable because
> of the way the conditions and results are listed in
> separate columns, and because the function arguments
> only have to be spelled out once.
I don't see that defining then using a function pointer
variable adds anything. I don't see anything wrong with
using the long expression (assuming it appears in the
program only once) directly as the function designator.
However the overall expression should be laid out
carefully so the different chunks stand out appropriately.
Here is a plausible try:
/* Choose among several functions to call on given argument list */
/* */
( offLmod == offRmod ? ror_d0
: minlen <= BITS ? ror_short
: offLmod < offRmod ? ror_long_dn
: ror_long_up
)(
bsL->data+offLdiv, bsR->data+offRdiv, offLmod, offRmod, minlen
);
The two main parts (function designator, and function arguments)
stand out as clearly distinct chunks, with the function call
indication (ie, the left parenthesis) separating them. Granted,
it may look a bit strange, but the situation is unusual, so
looking strange has some positive benefits in this case.
Of course, all this assumes that the pattern is isolated and
appears only once or twice in the program. If it appears
more often than that, very likely the program needs some
refactoring to separate out the common pattern.
|
|
0
|
|
|
|
Reply
|
txr1 (1213)
|
10/26/2009 10:18:32 AM
|
|
Richard Heathfield <rjh@see.sig.invalid> writes:
> In <JILEm.12398$U5.179864@newsb.telia.net>, Nisse Engstr@C3{B6}m wrote:
>
> <snip>
>
>> Here's another example, from a few years back:
>>
>> (offLmod == offRmod ? ror_d0 :
>> minlen <= BITS ? ror_short :
>> offLmod < offRmod ? ror_long_dn :
>> ror_long_up )
>> (bsL->data+offLdiv, bsR->data+offRdiv, offLmod, offRmod,
>> minlen);
>>
>> I realize now that maybe it should've been:
>>
>> void (*fptr)(/* args */) =
>> (offLmod == offRmod ? ror_d0 :
>> minlen <= BITS ? ror_short :
>> offLmod < offRmod ? ror_long_dn :
>> ror_long_up);
>
> Better still, wrap up the complexity in a function:
>
> typedef void ror_function_type( /* args */ );
>
> /* ... */
>
> ror_function_type *p = get_ror_function(offLmod, offRmod, etc!);
>
> (*p)(args);
Besides having an unneeded variable, this pattern seems suspect
because the two argument lists have a lot of overlap. If we're going
to go to the trouble of writing a function, it seems like there should
be one function with all the parameters, as for example,
rorX( offLmod, offRmod, minlen, BITS, bsL->data+offLdiv, bsR->data+offRdiv );
making the commonality more evident.
|
|
0
|
|
|
|
Reply
|
txr1 (1213)
|
10/26/2009 10:26:53 AM
|
|
In <kfnbpju1mdu.fsf@x-alumni2.alumni.caltech.edu>, Tim Rentsch wrote:
> Richard Heathfield <rjh@see.sig.invalid> writes:
>
<snip>
>> ror_function_type *p = get_ror_function(offLmod, offRmod, etc!);
>>
>> (*p)(args);
>
> Besides having an unneeded variable,
It also has unneeded whitespace. Variables (if you want to call them
that), like whitespace, can improve readability.
<snip>
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
|
|
0
|
|
|
|
Reply
|
rjh (10789)
|
10/26/2009 2:42:11 PM
|
|
raltbos@xs4all.nl (Richard Bos) writes:
> Ben Pfaff <blp@cs.stanford.edu> wrote:
>
>> Phil Carmody <thefatphil_demunged@yahoo.co.uk> writes:
>>
>> > printf("I see %u ship%s.\n", nships, "s"+(nships==1));
>>
>> This sort of thing is always clever, but it falls down badly when
>> you need to internationalize your code.
>
> True, but when you need that, there is no single printf() call that
> prints that sentence reliably. Even
>
> if (nships==1)
> printf(inter("I see 1 ship.\n"));
> else
> printf(inter("I see %u ships.\n"), nships);
>
> while a lot more internationalisable, is not enough to guarantee
> portability to all languages.
Fortunately, i18n libraries can deal with that, e.g.:
printf (ngettext ("I see %u ship.", "I see %u ships.", nship), nships);
--
"For those who want to translate C to Pascal, it may be that a lobotomy
serves your needs better." --M. Ambuhl
"Here are the steps to create a C-to-Turbo-Pascal translator..." --H. Schildt
|
|
0
|
|
|
|
Reply
|
blp (3953)
|
10/26/2009 3:34:07 PM
|
|
On Oct 25, 1:32=A0am, spinoza1111 <spinoza1...@yahoo.com> wrote:
> On Oct 24, 11:35=A0pm, Ben Pfaff <b...@cs.stanford.edu> wrote:
>
> > Phil Carmody <thefatphil_demun...@yahoo.co.uk> writes:
> > > printf("I see %u ship%s.\n", nships, "s"+(nships=3D=3D1));
>
> > This sort of thing is always clever, but it falls down badly when
> > you need to internationalize your code.
>
> So would the equivalent if else. I am aware that in practical
> internationalization, programmers are directed to use "resources" of
> strings with the "right" translations normally prepared by technical
> writers and translators. Correspondingly, they are discouraged in my
> experience from writing code like the above which seems and is rather
> clever...but ties the program to English, thereby increasing le
> dominance Anglo-Saxonne over tout le monde in fashion neo-colonialiste
> alors peut etre Fasciste.
>
> My own theory is that programmers should be widely and deeply cultured
> with the resulting awareness of when they are building in such a
> dependency. The problem being that most programmers are what the
> Russians would call ne kulterni and what Indian chaps call jungly.
Who do you get your weed from, and is he within driving distance of
San Francisco?
|
|
0
|
|
|
|
Reply
|
squeamz (108)
|
10/26/2009 7:56:42 PM
|
|
On Oct 26, 12:27=A0am, Tim Rentsch <t...@alumni.caltech.edu> wrote:
> "io_x" <a...@b.c.invalid> writes:
> > "user923005" <dcor...@connx.com> ha scritto nel messaggio
> >[snip performance questions]
>
> >>typedef int =A0 =A0 e_type;
>
> >>e_type =A0 =A0 =A0 =A0 =A0median3(e_type a, e_type b, e_type c)
> >>{
> >> =A0 =A0return (a < b) ? ((b < c) ? b : ((a < c) ? c : a)) : ((a < c) ?
> >>a : ((b < c) ? c : b));
> >>}
>
> > what about
> > e_type =A0 medianr(e_type a, e_type b, e_type c)
> > {e_type =A0r;
> > =A0if(a>c) {r=3Da, a=3Dc, =A0c=3Dr;}
> > =A0if(a>b) {r=3Da, a=3Db, =A0b=3Dr;}
> > =A0if(c<b) {r=3Dc, c=3Db, =A0b=3Dr;}
> > =A0return =A0b;
> > }
>
> In all these different variations of median, it's suprising that
> no one has emphasized obviousness of correctness. =A0For example,
>
> =A0 =A0...
> =A0 =A0#define CHECK(a,b,c) do if ((a)<=3D(b) && (b)<=3D(c)) return (b); =
while(0)
> =A0 =A0 =A0 CHECK(a,b,c);
> =A0 =A0 =A0 CHECK(a,c,b);
> =A0 =A0 =A0 CHECK(b,a,c);
> =A0 =A0 =A0 CHECK(b,c,a);
> =A0 =A0 =A0 CHECK(c,a,b);
> =A0 =A0 =A0 CHECK(c,b,a);
> =A0 =A0 =A0 assert(0);
> =A0 =A0 =A0 return =A00;
> =A0 =A0#undef CHECK
>
> or instead using the return form
>
> =A0 =A0#define CHECK(a,b,c) =A0((a)<=3D(b) && (b)<=3D(c)) =A0? =A0(b)
> =A0 =A0 =A0 return =A0CHECK(a,b,c)
> =A0 =A0 =A0 =A0 =A0: =A0 =A0CHECK(a,c,b)
> =A0 =A0 =A0 =A0 =A0: =A0 =A0CHECK(b,a,c)
> =A0 =A0 =A0 =A0 =A0: =A0 =A0CHECK(b,c,a)
> =A0 =A0 =A0 =A0 =A0: =A0 =A0CHECK(c,a,b)
> =A0 =A0 =A0 =A0 =A0: =A0 =A0CHECK(c,b,a)
> =A0 =A0 =A0 =A0 =A0: =A0 =A0(assert(0), 0);
> =A0 =A0#undef CHECK
>
> In either of these it's easy to tell at a glance that all
> cases are tested and that the appropriate value is returned
> in all cases.
There is a test for correctness in my test driver.
|
|
0
|
|
|
|
Reply
|
dcorbit (2696)
|
10/26/2009 8:04:25 PM
|
|
On Oct 24, 11:35=A0pm, "io_x" <a...@b.c.invalid> wrote:
> "io_x" <a...@b.c.invalid> ha scritto nel messaggionews:4ae32865$0$1117$4f=
afbaef@reader1.news.tin.it...
>
>
>
>
>
>
>
> > "user923005" <dcor...@connx.com> ha scritto nel messaggio
> >news:c70d29fe-48dc-44b8-9995-95dcf59df129@s21g2000prm.googlegroups.com..=
..
> >>/*
> >>Surprising to me, the switch ran 4x slower than the simple if() tests.
>
> >>It appears that the missed branch predictions are killer.
> >>I guess that profile guided optimization will help your routine
> >>quite a bit if the data has some particular pattern.
> >>*/
>
> >>typedef int =A0 =A0 e_type;
>
> >>e_type =A0 =A0 =A0 =A0 =A0median3(e_type a, e_type b, e_type c)
> >>{
> >> =A0 =A0return (a < b) ? ((b < c) ? b : ((a < c) ? c : a)) : ((a < c) ?
> >>a : ((b < c) ? c : b));
> >>}
>
> > what about
> > e_type =A0 medianr(e_type a, e_type b, e_type c)
> > {e_type =A0r;
> > if(a>c) {r=3Da, a=3Dc, =A0c=3Dr;}
> > if(a>b) {r=3Da, a=3Db, =A0b=3Dr;}
> > if(c<b) {r=3Dc, c=3Db, =A0b=3Dr;}
> > return =A0b;
> > }
>
> > or
> > -------------------
> > section _DATA use32 public class=3DDATA
> > global _medianrAsm
> > section _TEXT use32 public class=3DCODE
>
> > ; medianrAsm(r, a, c)
> > ; 0ra, 4P1, 8P2, 12P3
> > _medianrAsm:
> > =A0 =A0 =A0 =A0 =A0mov =A0 =A0 edx, =A0dword[esp+ =A04]
> > =A0 =A0 =A0 =A0 =A0mov =A0 =A0 eax, =A0dword[esp+ =A08]
> > =A0 =A0 =A0 =A0 =A0mov =A0 =A0 ecx, =A0dword[esp+ 12]
> > =A0 =A0 =A0 =A0 =A0cmp =A0 =A0 edx, =A0ecx
> > =A0 =A0 =A0 =A0 =A0jle =A0 =A0 .1
> > =A0 =A0 =A0 =A0 =A0xchg =A0 =A0edx, =A0ecx
> > .1: =A0 =A0 =A0 cmp =A0 =A0 edx, =A0eax
> > =A0 =A0 =A0 =A0 =A0jle =A0 =A0 .2
> > =A0 =A0 =A0 =A0 =A0xchg =A0 =A0eax, =A0edx
> > .2: =A0 =A0 =A0 cmp =A0 =A0 ecx, =A0eax
> > =A0 =A0 =A0 =A0 =A0jge =A0 =A0 .3
> > =A0 =A0 =A0 =A0 =A0xchg =A0 =A0eax, =A0ecx
> > .3:
> > =A0 =A0 =A0 =A0 =A0ret
> > -------------------------
>
> with
> -------
> section _DATA use32 public class=3DDATA
>
> global _medianrAsm
>
> section _TEXT use32 public class=3DCODE
>
> ; a r c
> ; 0 1 2 -
> ; medianrAsm(r, a, c)
> ; 0ra, 4P1, 8P2, 12P3
> =A0 =A0 =A0 =A0 =A0 align =A0 8
> _medianrAsm:
> =A0 =A0 =A0 =A0 =A0 mov =A0 =A0 eax, =A0dword[esp+ =A04]
> =A0 =A0 =A0 =A0 =A0 mov =A0 =A0 edx, =A0dword[esp+ =A08]
> =A0 =A0 =A0 =A0 =A0 mov =A0 =A0 ecx, =A0dword[esp+ =A012]
> =A0 =A0 =A0 =A0 =A0 cmp =A0 =A0 eax, =A0ecx
> =A0 =A0 =A0 =A0 =A0 jle =A0 =A0 .1
> =A0 =A0 =A0 =A0 =A0 xchg =A0 =A0eax, =A0ecx
> ; =A0 a<=3Dc =A0 0<=3D2
> .1: =A0 =A0 =A0 cmp =A0 =A0 edx, =A0eax
> =A0 =A0 =A0 =A0 =A0 jg =A0 =A0 =A0.2
> =A0 =A0 =A0 =A0 =A0 ret =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; r<=3Da<=3Dc=
=A01<=3D0<=3D2
> .2: =A0 =A0 =A0 cmp =A0 =A0 ecx, =A0edx
> =A0 =A0 =A0 =A0 =A0 jg =A0 =A0 =A0.3
> =A0 =A0 =A0 =A0 =A0 mov =A0 =A0 eax, =A0ecx
> =A0 =A0 =A0 =A0 =A0 ret =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; a<=3Dc<=3Dr=
=A00<=3D2<=3D1
> .3: =A0 =A0 =A0 mov =A0 =A0 eax, =A0edx =A0 =A0 ; a<=3Dr<=3Dc
> =A0 =A0 =A0 =A0 =A0 ret
> ---
>
> Prova median3
> m=3D843962432 =A0Result: 29.000000
> --------------
> Prova median3a
> m=3D843962432 =A0Result: 28.000000
> --------------
> Prova median3b
> m=3D843962432 =A0Result: 43.000000
> --------------
> Prova medianr
> m=3D843962432 =A0Result: 29.000000
> --------------
> Prova medianrAsm
> m=3D843962432 =A0Result: 28.000000
> --------------
>
> they are all of the same speed but
> median3b
> seems slower
>
> ------------------------
> #define P printf
>
> /*
> Surprising to me, the switch ran 4x slower than the simple if() tests.
>
> It appears that the missed branch predictions are killer.
> I guess that profile guided optimization will help your routine
> quite a bit if the data has some particular pattern.
> */
>
> typedef int =A0 =A0 e_type;
>
> e_type =A0 =A0 =A0 =A0 =A0median3(e_type a, e_type b, e_type c)
> {
> =A0 =A0 return (a < b) ? ((b < c) ? b : ((a < c) ? c : a)) : ((a < c) ?
> a : ((b < c) ? c : b));
>
> }
>
> e_type =A0 medianrAsm(e_type a, e_type b, e_type c);
>
> e_type =A0 medianr(e_type a, e_type b, e_type c)
> {e_type =A0r;
> =A0if(a>c) {r=3Da; a=3Dc; =A0c=3Dr;}
> /* =A0a<c =A0*/
> =A0if(a>b) return =A0a;
> =A0if(c<b) return =A0c; /* =A0a<c<b =A0*/
> =A0return =A0b;
>
> }
>
> e_type =A0 =A0 =A0 =A0 =A0 =A0 median3a(e_type a, e_type b, e_type c)
> {
> =A0 =A0 if (a < b) {
> =A0 =A0 =A0 =A0 if (b < c)
> =A0 =A0 =A0 =A0 =A0 =A0 return b; =A0 =A0 =A0 =A0 =A0 /* a b c */
> =A0 =A0 =A0 =A0 if (c < a)
> =A0 =A0 =A0 =A0 =A0 =A0 return a; =A0 =A0 =A0 =A0 =A0 /* c a b */
> =A0 =A0 =A0 =A0 return c; =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* a c b */
> =A0 =A0 } else {
> =A0 =A0 =A0 =A0 if (a < c)
> =A0 =A0 =A0 =A0 =A0 =A0 return a; =A0 =A0 =A0 =A0 =A0 /* b a c */
> =A0 =A0 =A0 =A0 if (c < b)
> =A0 =A0 =A0 =A0 =A0 =A0 return b; =A0 =A0 =A0 =A0 =A0 /* c b a */
> =A0 =A0 =A0 =A0 return c; =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* b c a */
> =A0 =A0 }
>
> }
>
> e_type =A0 =A0 =A0 =A0 =A0 =A0 median3b(e_type a, e_type b, e_type c)
> {
> =A0 =A0 switch ((a > b) + ((b > c) << 1) + ((c > a) << 2)) {
> =A0 =A0 case 0:
> =A0 =A0 =A0 =A0 return a;
> =A0 =A0 case 1:
> =A0 =A0 =A0 =A0 return c;
> =A0 =A0 case 2:
> =A0 =A0 =A0 =A0 return a;
> =A0 =A0 case 3:
> =A0 =A0 =A0 =A0 return b;
> =A0 =A0 case 4:
> =A0 =A0 =A0 =A0 return b;
> =A0 =A0 case 5:
> =A0 =A0 =A0 =A0 return a;
> =A0 =A0 case 6:
> =A0 =A0 default:
> =A0 =A0 =A0 =A0 return c;
> =A0 =A0 }
>
> }
>
> #include <stdio.h>
> #include =A0<time.h>
> #include =A0<stdlib.h>
>
> double =A0prova(e_type =A0(*f)(e_type, e_type, e_type))
> {time_t =A0 t1, t2;
> =A0double =A0 =A0 =A0 =A0d;
> =A0e_type =A0i, j, k, m=3D0, m1, m2;
>
> =A0t1=3Dtime(0);
> =A0for(i=3D0; i<1000; i++)
> =A0 =A0for(j=3D0; j<1000; j++)
> =A0 =A0 =A0 for (k=3D0; k<3000; k++)
> =A0 =A0 =A0 =A0 {m1=3Di^j; m2=3Di^k;
> =A0 =A0 =A0 =A0 =A0m +=3D f(m1, i, m2);
> =A0 =A0 =A0 =A0 }
> =A0t2=3Dtime(0);
> =A0d=3Ddifftime(t2, t1);
> =A0P("m=3D%u =A0", (unsigned) m);
> =A0return =A0d;
>
> }
>
> double =A0prova1(e_type =A0(*f)(e_type, e_type, e_type))
> {time_t =A0 t1, t2;
> =A0double =A0 =A0 =A0 =A0d;
> =A0e_type =A0i, j, k, m=3D0, kk;
>
> =A0t1=3Dtime(0);
> =A0for(kk=3D0; kk<300000000 ; ++kk)
> =A0 =A0 =A0 =A0{i=3Drand(); j=3Drand(); k=3Drand();
> =A0 =A0 =A0 =A0 m+=3Df(i, j, k);
> =A0 =A0 =A0 =A0}
> =A0t2=3Dtime(0);
> =A0d=3Ddifftime(t2, t1);
> =A0P("m=3D%u =A0", (unsigned) m);
> =A0return =A0d;
>
> }
>
> int =A0 =A0 =A0 =A0 =A0 =A0 main(void)
> { =A0 double =A0 =A0 =A0 =A0 =A0h;
> =A0 =A0 e_type =A0 =A0 =A0 =A0 =A0i,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 j,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 k,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 m,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 m2,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 m3;
> =A0 =A0 for (i =3D 0; i < 300; i++)
> =A0 =A0 =A0 =A0 for (j =3D 0; j < 300; j++)
> =A0 =A0 =A0 =A0 =A0 =A0 for (k =3D 0; k < 300; k++) {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 m =3D median3(i, j, k);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 m2 =3D medianr(i, j, k);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 m3 =3D medianrAsm(i, j, k);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (m3 !=3D m)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0{printf("Disagreement of %d verses=
%d\n", m3, m);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 printf("median of %d %d %d is %d\=
n", i, j, k, m3);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return =A00;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0}
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (m2 !=3D m)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0{printf("Disagreement of %d verses=
%d\n", m2, m);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 printf("median of %d %d %d is %d\=
n", i, j, k, m2);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return =A00;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0}
> =A0 =A0 =A0 =A0 =A0 =A0 }
>
> =A0P("Prova median3\n");
> =A0h=3Dprova(median3);
> =A0P("Result: %f\n", h);
> =A0P("--------------\n");
>
> =A0P("Prova median3a\n");
> =A0h=3Dprova(median3a);
> =A0P("Result: %f\n", h);
> =A0P("--------------\n");
>
> =A0P("Prova median3b\n");
> =A0h=3Dprova(median3b);
> =A0P("Result: %f\n", h);
> =A0P("--------------\n");
>
> =A0P("Prova medianr\n");
> =A0h=3Dprova(medianr);
> =A0P("Result: %f\n", h);
> =A0P("--------------\n");
>
> =A0P("Prova medianrAsm\n");
> =A0h=3Dprova(medianrAsm);
> =A0P("Result: %f\n", h);
> =A0P("--------------\n");
>
> =A0return 0;
>
>
>
> }
My result:
typedef int e_type;
e_type
median3(e_type a, e_type b, e_type c)
{
return (a < b) ? ((b < c) ? b : ((a < c) ? c : a)) : ((a < c) ?
a : ((b < c) ? c : b));
}
e_type
median3a(e_type a, e_type b, e_type c)
{
if (a < b) {
if (b < c)
return b; /* a b c */
if (c < a)
return a; /* c a b */
return c; /* a c b */
} else {
if (a < c)
return a; /* b a c */
if (c < b)
return b; /* c b a */
return c; /* b c a */
}
}
e_type
median3b(e_type a, e_type b, e_type c)
{
switch ((a > b) + ((b > c) << 1) + ((c > a) << 2)) {
case 0:
return a;
case 1:
return c;
case 2:
return a;
case 3:
return b;
case 4:
return b;
case 5:
return a;
case 6:
default:
return c;
}
}
e_type
median3c(e_type a, e_type b, e_type c)
{
e_type elist[7] =3D
{a, c, a, b, b, a, c};
return elist[(a > b) + ((b > c) << 1) + ((c > a) << 2)];
}
e_type
median3d(e_type a, e_type b, e_type c)
{
e_type *pa =3D &a;
e_type *pb =3D &b;
e_type *pc =3D &c;
const e_type *elist[7] =3D
{pa, pc, pa, pb, pb, pa, pc};
return *elist[(a > b) + ((b > c) << 1) + ((c > a) << 2)];
}
e_type
median3e(e_type a, e_type b, e_type c)
{
/* 2.0 1.1 0.2 0 */
switch ((0x2148U >> ((((a > b) << 1) + ((b > c) << 2) + ((c > a)
<< 3)))) & 3) {
case 0:
return a;
case 1:
return b;
case 2:
default:
return c;
}
}
e_type
median3f(e_type a, e_type b, e_type c)
{
/* 2.0 1.1 0.2 0 */
return (((0x2148U >> ((((a > b) << 1) + ((b > c) << 2) + ((c > a)
<< 3)))) & 3) =3D=3D 0) * a
+ (((0x2148U >> ((((a > b) << 1) + ((b > c) << 2) + ((c >
a) << 3)))) & 3) =3D=3D 1) * b
+ (((0x2148U >> ((((a > b) << 1) + ((b > c) << 2) + ((c >
a) << 3)))) & 3) =3D=3D 2) * c
;
}
e_type
median3g(e_type a, e_type b, e_type c)
{
/* register */
unsigned tmp;
/* 2.0 1.1 0.2 0 */
tmp =3D ((0x2148U >> ((((a > b) << 1) + ((b > c) << 2) + ((c > a) <<
3)))) & 3);
return tmp & 2 ? c : tmp ? b : a;
}
e_type
median3h(e_type a, e_type b, e_type c)
{
e_type r;
if (a > c) {
r =3D a, a =3D c, c =3D r;
}
if (a > b) {
r =3D a, a =3D b, b =3D r;
}
if (c < b) {
r =3D c, c =3D b, b =3D r;
}
return b;
}
#ifdef UNIT_TEST
#include <stdio.h>
int main(void)
{
e_type i,
j,
k,
m,
m2,
m3,
m4,
m5,
m6,
m7,
m8,
m9;
for (i =3D 0; i < 3000; i++)
for (j =3D 0; j < 3000; j++)
for (k =3D 0; k < 3000; k++) {
m =3D median3(i, j, k);
m2 =3D median3a(i, j, k);
m3 =3D median3b(i, j, k);
m4 =3D median3c(i, j, k);
m5 =3D median3d(i, j, k);
m6 =3D median3e(i, j, k);
m7 =3D median3f(i, j, k);
m8 =3D median3g(i, j, k);
m9 =3D median3h(i, j, k);
#ifdef SHOW_RESULTS
printf("median of %d %d %d is %d\n", i, j, k, m3);
#endif
if (m9 !=3D m)
printf("Disagreement (9) of %d verses %d\n", m9,
m);
if (m8 !=3D m)
printf("Disagreement (8) of %d verses %d\n", m8,
m);
if (m7 !=3D m)
printf("Disagreement (7) of %d verses %d\n", m7,
m);
if (m6 !=3D m)
printf("Disagreement (6) of %d verses %d\n", m6,
m);
if (m5 !=3D m)
printf("Disagreement (5) of %d verses %d\n", m5,
m);
if (m4 !=3D m)
printf("Disagreement (4) of %d verses %d\n", m4,
m);
if (m3 !=3D m)
printf("Disagreement (3) of %d verses %d\n", m3,
m);
if (m2 !=3D m)
printf("Disagreement (2) of %d verses %d\n", m2,
m);
}
return 0;
}
#endif
/*
Profile results were:
Function Name,Exclusive Samples,Exclusive Samples %,
"median3f","73,811",18.50,
"main","58,858",14.75,
"median3d","58,253",14.60,
"median3g","49,352",12.37,
"median3c","44,832",11.23,
"median3b","42,708",10.70,
"median3e","33,287",8.34,
"median3h","16,757",4.20,
"median3a","10,822",2.71,
"median3","10,380",2.60,
*/
|
|
0
|
|
|
|
Reply
|
dcorbit (2696)
|
10/26/2009 8:05:22 PM
|
|
On Mon, 26 Oct 2009 03:18:32 -0700, Tim Rentsch wrote:
> I don't see that defining then using a function pointer
> variable adds anything. I don't see anything wrong with
> using the long expression (assuming it appears in the
> program only once) directly as the function designator.
It adds a little readability for me. Or at least it did.
On further inspection, it seems that the long version
wasn't actually bad. Your milage may vary. Mine does.
> However the overall expression should be laid out
> carefully so the different chunks stand out appropriately.
> Here is a plausible try:
>
> /* Choose among several functions to call on given argument list */
> /* */
> ( offLmod == offRmod ? ror_d0
> : minlen <= BITS ? ror_short
> : offLmod < offRmod ? ror_long_dn
> : ror_long_up
> )(
> bsL->data+offLdiv, bsR->data+offRdiv, offLmod, offRmod, minlen
> );
It's not god-awful, but it's far from an improvement.
My money stays on the first horse.
/Nisse
|
|
0
|
|
|
|
Reply
|
news.NOSPAM.wbarspjz (4)
|
10/27/2009 2:12:01 PM
|
|
Ben Pfaff <blp@cs.stanford.edu> wrote:
> raltbos@xs4all.nl (Richard Bos) writes:
> > Ben Pfaff <blp@cs.stanford.edu> wrote:
> >> Phil Carmody <thefatphil_demunged@yahoo.co.uk> writes:
> >>
> >> > printf("I see %u ship%s.\n", nships, "s"+(nships==1));
> >>
> >> This sort of thing is always clever, but it falls down badly when
> >> you need to internationalize your code.
> >
> > True, but when you need that, there is no single printf() call that
> > prints that sentence reliably. Even
> >
> > if (nships==1)
> > printf(inter("I see 1 ship.\n"));
> > else
> > printf(inter("I see %u ships.\n"), nships);
> >
> > while a lot more internationalisable, is not enough to guarantee
> > portability to all languages.
>
> Fortunately, i18n libraries can deal with that, e.g.:
> printf (ngettext ("I see %u ship.", "I see %u ships.", nship), nships);
That, OTOH, seems overkill to me; all you should need (as well as what
you need at the very least) is
printf(ngettext("I see %u ships.\n", nship), nship);
What you need is the properly internationalised text for "I see N
ship(s)." The _internationalisation_ library should not need to know
that the _English_ singular for ships is ship. (Unless, of course, your
local language is English; but in that case, _it_ should give you that
English singular, and not rely on the user-programmer to specify it for
that language alone.)
Richard
|
|
0
|
|
|
|
Reply
|
raltbos (821)
|
10/27/2009 6:58:07 PM
|
|
raltbos@xs4all.nl (Richard Bos) writes:
> Ben Pfaff <blp@cs.stanford.edu> wrote:
>> Fortunately, i18n libraries can deal with that, e.g.:
>> printf (ngettext ("I see %u ship.", "I see %u ships.", nship), nships);
>
> That, OTOH, seems overkill to me; all you should need (as well as what
> you need at the very least) is
>
> printf(ngettext("I see %u ships.\n", nship), nship);
>
> What you need is the properly internationalised text for "I see N
> ship(s)." The _internationalisation_ library should not need to know
> that the _English_ singular for ships is ship. (Unless, of course, your
> local language is English; but in that case, _it_ should give you that
> English singular, and not rely on the user-programmer to specify it for
> that language alone.)
Your approach makes it impossible to produce grammatical output
in any language at all on a system that lacks functioning i18n
libraries and message catalogs (and being able to locate and read
the message catalogs at runtime), whereas with the approach
actually used this is as simple as invoking a stub of the form
"return n == 1 ? singular : plural;".
--
Ben Pfaff
http://benpfaff.org
|
|
0
|
|
|
|
Reply
|
blp (3953)
|
10/27/2009 7:48:29 PM
|
|
Ben Pfaff wrote:
> raltbos@xs4all.nl (Richard Bos) writes:
>
>> Ben Pfaff <blp@cs.stanford.edu> wrote:
>>> Fortunately, i18n libraries can deal with that, e.g.:
>>> printf (ngettext ("I see %u ship.", "I see %u ships.", nship),
>>> nships);
>>
>> That, OTOH, seems overkill to me; all you should need (as well as
>> what you need at the very least) is
>>
>> printf(ngettext("I see %u ships.\n", nship), nship);
>>
>> What you need is the properly internationalised text for "I see N
>> ship(s)." The _internationalisation_ library should not need to know
>> that the _English_ singular for ships is ship. (Unless, of course,
>> your local language is English; but in that case, _it_ should give
>> you that English singular, and not rely on the user-programmer to
>> specify it for that language alone.)
>
> Your approach makes it impossible to produce grammatical output
> in any language at all on a system that lacks functioning i18n
> libraries and message catalogs (and being able to locate and read
> the message catalogs at runtime), whereas with the approach
> actually used this is as simple as invoking a stub of the form
> "return n == 1 ? singular : plural;".
Or you can just use:
printf("I see %u ship(s).\n",nships);
This is the approach of Vista, so it must be OK.
--
Bartc
|
|
0
|
|
|
|
Reply
|
bartc (783)
|
10/27/2009 9:24:53 PM
|
|
Gareth Owen <gwowen@gmail.com> writes:
> Tim Rentsch <txr@alumni.caltech.edu> writes:
>
>> The ?: operator is not some obscure corner of C, nor does using it
>> automatically qualify as an idiom. If someone who claims to know C
>> can't both read and write C code that has an occasional use of ?:,
>> he or she isn't worthy of being called a programmer.
>
> Can you lay off "the isn't worthy of being called a programmer"
> schtick. It's incredibly patronising.
My comments were no more patronizing or condescending than the
comments of yours (snipped out of your reply) that I was
responding to.
> I've never argued about programmers who "can" or "can't".
> Comprehension is not a binary "can comprehend" and "can't comprehend".
> I can comprehend the writing of JK Rowling and James Joyce, but one
> of them is lot less work. But, I'd like to think that good
> programmers would strive to be more like the former than the latter.
> Good authors, maybe not.
This analogy misses the point, IMO, in several different ways.
C has a precise semantics; English does not. All programmers
write code as well as read it, whereas readers of English typically
don't also write, at least not on the scale of whole books.
Moreover the difference in scale makes the offered comparison
rather pointless -- in code the writing under consideration
is one "clause" of one "sentence", but the books are many
chapters of many paragraphs of (usually) multiple sentences
each. A better analogy would be to ask if someone understands
the difference between a restrictive clause and a non-restrictive
clause, which any competent writer will.
> I can read comprehend ?:, and in simple expressions it can be much
> more eloquent. There are places where the brevity of ?: gives a
> program extra clarity for the reader. But when the expressions are
> complex that clarity is lost, comprehension becomes much harder work
> and the only gain is a little less typing. That's a poor tradeoff, if
> your code is ever to be maintained by people less eloquent in C than
> yourself.
If you'll recall the comments in your earlier posting were
written in response to the text
(upthread)>> [... on expressions like 'a = b ? c : d' ...]
So the comments above need to be made a bit more explicit
if you want them to convey any significant amount of useful
information.
> My point is merely this. If I use ?: in complex expressions, what is
> the benefit and what do I gain?
That isn't a point, it's a question. If the posting had asked a
question (and meant it as a question) the response/answer to it
would have been quite different. Of course it's often true that
people ask rhetorical questions as a way of making a point
rather than meaning it as a question. In my experience this
usually means either that they don't really know just what
their point is or they're afraid to say it straight out
because if said directly the ridiculousness of the comment
would be obvious. So if there's something you want to
say (or a question you want to ask), my advice is to
say it (or ask it) clearly and directly.
|
|
0
|
|
|
|
Reply
|
txr1 (1213)
|
10/28/2009 1:09:46 PM
|
|
user923005 <dcorbit@connx.com> writes:
> On Oct 26, 12:27 am, Tim Rentsch <t...@alumni.caltech.edu> wrote:
>> "io_x" <a...@b.c.invalid> writes:
>> > "user923005" <dcor...@connx.com> ha scritto nel messaggio
>> >[snip performance questions]
>>
>> >>typedef int e_type;
>>
>> >>e_type median3(e_type a, e_type b, e_type c)
>> >>{
>> >> return (a < b) ? ((b < c) ? b : ((a < c) ? c : a)) : ((a < c) ?
>> >>a : ((b < c) ? c : b));
>> >>}
>>
>> > what about
>> > e_type medianr(e_type a, e_type b, e_type c)
>> > {e_type r;
>> > if(a>c) {r=a, a=c, c=r;}
>> > if(a>b) {r=a, a=b, b=r;}
>> > if(c<b) {r=c, c=b, b=r;}
>> > return b;
>> > }
>>
>> In all these different variations of median, it's suprising that
>> no one has emphasized obviousness of correctness. For example,
>>
>> ...
>> #define CHECK(a,b,c) do if ((a)<=(b) && (b)<=(c)) return (b); while(0)
>> CHECK(a,b,c);
>> CHECK(a,c,b);
>> CHECK(b,a,c);
>> CHECK(b,c,a);
>> CHECK(c,a,b);
>> CHECK(c,b,a);
>> assert(0);
>> return 0;
>> #undef CHECK
>>
>> or instead using the return form
>>
>> #define CHECK(a,b,c) ((a)<=(b) && (b)<=(c)) ? (b)
>> return CHECK(a,b,c)
>> : CHECK(a,c,b)
>> : CHECK(b,a,c)
>> : CHECK(b,c,a)
>> : CHECK(c,a,b)
>> : CHECK(c,b,a)
>> : (assert(0), 0);
>> #undef CHECK
>>
>> In either of these it's easy to tell at a glance that all
>> cases are tested and that the appropriate value is returned
>> in all cases.
>
> There is a test for correctness in my test driver.
Having a unit test is orthogonal to the point I was making.
Not that I think having a unit test is pointless, far from
it, but that doesn't affect the clarity/obviousness of
the original code. (And there is always the question of
whether the unit test is testing the right thing.) Ideally
there would be both: code whose correctness is obvious,
_and_ some sort of test scaffolding to increase our
confidence that it computes good results rather than bad.
|
|
0
|
|
|
|
Reply
|
txr1 (1213)
|
10/28/2009 1:16:22 PM
|
|
Richard Heathfield <rjh@see.sig.invalid> writes:
> In <kfnbpju1mdu.fsf@x-alumni2.alumni.caltech.edu>, Tim Rentsch wrote:
>
>> Richard Heathfield <rjh@see.sig.invalid> writes:
>>
> <snip>
>
>>> ror_function_type *p = get_ror_function(offLmod, offRmod, etc!);
>>>
>>> (*p)(args);
>>
>> Besides having an unneeded variable,
>
> It also has unneeded whitespace. Variables (if you want to call them
> that), like whitespace, can improve readability.
Whether deliberately or not, you're misinterpreting or
misunderstanding me. Of course using variables _can_
improve readability, but "can" doesn't always mean "does".
Same is true for whitespace. The whitespace in the
above example is "needed" in that leaving it out
would (IMO) lessen readability. The variable is
unneeded because (again IMO) putting it in does
little or nothing to improve readability.
|
|
0
|
|
|
|
Reply
|
txr1 (1213)
|
10/28/2009 1:26:39 PM
|
|
Nisse Engström <news.NOSPAM.wbarspjz@luden.se> writes:
> On Mon, 26 Oct 2009 03:18:32 -0700, Tim Rentsch wrote:
>
>> I don't see that defining then using a function pointer
>> variable adds anything. I don't see anything wrong with
>> using the long expression (assuming it appears in the
>> program only once) directly as the function designator.
>
> It adds a little readability for me. Or at least it did.
> On further inspection, it seems that the long version
> wasn't actually bad. Your milage may vary. Mine does.
I took your statement as a one-off rather than intending
to express a general principle, which I think is how
you meant it. A different context might yield a different
result.
>> However the overall expression should be laid out
>> carefully so the different chunks stand out appropriately.
>> Here is a plausible try:
>>
>> /* Choose among several functions to call on given argument list */
>> /* */
>> ( offLmod == offRmod ? ror_d0
>> : minlen <= BITS ? ror_short
>> : offLmod < offRmod ? ror_long_dn
>> : ror_long_up
>> )(
>> bsL->data+offLdiv, bsR->data+offRdiv, offLmod, offRmod, minlen
>> );
>
> It's not god-awful, but it's far from an improvement.
> My money stays on the first horse.
On a personal level I had a similar reaction to the
earlier form. But there's another way to approach
the problem, namely, devise a test and try to measure
some objective differences. After that there may be
something useful to talk about.
|
|
0
|
|
|
|
Reply
|
txr1 (1213)
|
10/28/2009 1:37:11 PM
|
|
In <kfniqdzzm28.fsf@x-alumni2.alumni.caltech.edu>, Tim Rentsch wrote:
> Richard Heathfield <rjh@see.sig.invalid> writes:
>
>> In <kfnbpju1mdu.fsf@x-alumni2.alumni.caltech.edu>, Tim Rentsch
>> wrote:
>>
>>> Richard Heathfield <rjh@see.sig.invalid> writes:
>>>
>> <snip>
>>
>>>> ror_function_type *p = get_ror_function(offLmod, offRmod, etc!);
>>>>
>>>> (*p)(args);
>>>
>>> Besides having an unneeded variable,
>>
>> It also has unneeded whitespace. Variables (if you want to call
>> them that), like whitespace, can improve readability.
>
> Whether deliberately or not, you're misinterpreting or
> misunderstanding me.
Perhaps, but (a) it's not deliberate and (b) I'm not sure how.
> Of course using variables _can_
> improve readability, but "can" doesn't always mean "does".
Agreed. But in this case, I think it breaks up unnecessarily complex
code.
> Same is true for whitespace. The whitespace in the
> above example is "needed" in that leaving it out
> would (IMO) lessen readability. The variable is
> unneeded because (again IMO) putting it in does
> little or nothing to improve readability.
Then that would be the nub of our disagreement. One man's readability
is another man's unnecessary redundancy[1].
Personally, I am of the opinion that expressions should be reasonably
un-"busy", and the expression in question seemed to me to be doing
too much in a single step.
[1] Yes, I know.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
|
|
0
|
|
|
|
Reply
|
rjh (10789)
|
10/28/2009 2:09:29 PM
|
|
|
134 Replies
33 Views
(page loaded in 1.004 seconds)
|