The problem I started thinking about is WHY IN THE WORLD WOULD ANYONE
USE SHORT INTS IN A PROGRAM, particularly one done for a workstation-level
machine (i.e., large memory model, etc). I can see the need for memory
conservation to some degree, but certainly there is no performance
benefit on most machines today (there may even be a performance penalty
in obscure cases). I can also see the need to store short ints on disk
for databases since memory can multiply radically when you have large
databases. But for in-memory structures, particularly counters and indexes
and thinks like that, there is simply no justification to use short ints.
In a related conversation, someone mentioned that many organizations have
coding standards that let them redefine the size of ints to keep this
from happening. For instance use int1, int2 and int4 as typedefs and you
can make them whatever you want. This is where the thought struck me that
makes me curious to get other peoples' opinion on. Why would you EVER
use NUMBERS in a program. Except in TWO places: inside quoted strings
and on the right side of #defs (or the equivalent depending on the
language). There is no justification for using a number in a variable
name or typedef or whatever. The above example should be vsi, si and li
or shint, regint, lngint or something like that. JUST NAMES, NOT NUMBERS.
Why? Because using numbers causes a confusion in the event that you
decide to change the platform or the concept. It is fair to say that
a lngint must be equal to or longer than a regint, but I contend it is
erroneous and misleading to say that an int4 must be EQUAL TO or longer
than an int2. Longer than, maybe, but EQUAL TO? That is just wrong.
In fact, int4 and int2, by normal thought processes, expresses an exact
2:1 relationship. And the fact that I can change that in a hidden way
does NOT make things clearer, it makes things muddier.
So I suggest a coding standard: numbers should be barred from use in
variable and type names. Only letters can be used. Numbers can only
appear where you define manifest constants (#def, const, etc.) to
names and inside strings (where they generally do no harm).
Any comments?
Jon Rosen
j...@redbrick.com
-----------------------------------------------------------------
"Where is the wisdom? Lost in the knowledge.
Where is the knowledge? Lost in the information." -- T.S. Eliot
"Where is the information? Lost in the data.
Where is the data? Lost in the #@$%?!& database." -- Joe Celko
-----------------------------------------------------------------
Have you thought this through? Do you really think that
x *= TWO;
or
#define DOUBLE(x) ((x)*=2)
DOUBLE(X);
is preferable to just
x *= 2;
?
There is no justification for using a number in a variable
> name or typedef or whatever.
Sure there is! What about
struct headers *rfc822(char *message) {...}
or
srand48()
or even
wait3()
?
The above example should be vsi, si and li
> or shint, regint, lngint or something like that. JUST NAMES, NOT NUMBERS.
> Why? Because using numbers causes a confusion in the event that you
> decide to change the platform or the concept. It is fair to say that
> a lngint must be equal to or longer than a regint, but I contend it is
> erroneous and misleading to say that an int4 must be EQUAL TO or longer
> than an int2. Longer than, maybe, but EQUAL TO? That is just wrong.
> In fact, int4 and int2, by normal thought processes, expresses an exact
> 2:1 relationship. And the fact that I can change that in a hidden way
> does NOT make things clearer, it makes things muddier.
In this case, maybe. In general? Probably not. But even if you're
right, your next statement is draconian and (pardon me but I must be
blunt) stupid.
> So I suggest a coding standard: numbers should be barred from use in
> variable and type names. Only letters can be used. Numbers can only
> appear where you define manifest constants (#def, const, etc.) to
> names and inside strings (where they generally do no harm).
>
> Any comments?
Sorry, but I disagree.
--tod
>So I suggest a coding standard: numbers should be barred from use in
>variable and type names. Only letters can be used. Numbers can only
>appear where you define manifest constants (#def, const, etc.) to
>names and inside strings (where they generally do no harm).
>Any comments?
yes. what about if i use two strings named string1 and string2?
I know I could use an array, or name them better, but alot of times it
is more convenient just to number them, e.g.
void Line(x1,y1,x2,y2)
int x1,x2,y1,y2;
{
...
}
just my $0.02.
--
--------------------------------------------------------------------
******* Tim Hollebeek ==> thol...@ursa.calvin.edu *******
The best thing about growing older is that it takes such a long time.
>j...@RedBrick.COM writes:
>> Why would you EVER
>> use NUMBERS in a program. Except in TWO places: inside quoted strings
>> and on the right side of #defs (or the equivalent depending on the
>> language).
>Have you thought this through? Do you really think that
> x *= TWO;
>or
> #define DOUBLE(x) ((x)*=2)
> DOUBLE(X);
>is preferable to just
> x *= 2;
>?
No, no, no. He just meant using numeric characters inside of symbols.
Literal constants are ok.
--
--------------------------------------------------------------------
******* Tim Hollebeek ==> thol...@ursa.calvin.edu *******
Conscience is the inner voice that warns us somebody is looking
-- H. L. Mencken
>So I suggest a coding standard: numbers should be barred from use in
>variable and type names. Only letters can be used. Numbers can only
>appear where you define manifest constants (#def, const, etc.) to
>names and inside strings (where they generally do no harm).
>Any comments?
But, Jon, what about all my loop variables (i1,i2,i3,i4) ;-)
----------------------------------------------------------------------------
"This must be Thursday. I never could get the hang of Thursdays"
- Douglas Adams
- Patrick Taylor (Arthur Dent)
Ericsson Network Systems
exu...@exu.ericsson.se "Don't let the .se fool you"
or exu...@ZGNews.Lonestar.Org, exu.e...@memo.ericsson.se
>So I suggest a coding standard: numbers should be barred from use in
>variable and type names. Only letters can be used. Numbers can only
>appear where you define manifest constants (#def, const, etc.) to
>names and inside strings (where they generally do no harm).
>Any comments?
A friend of mine once accused me of writing spaghetti code, because
had written
count := count + 1
He insisted that it should be
count := succ(count)
He is a physics major, BTW
Klaus O K
>But, Jon, what about all my loop variables (i1,i2,i3,i4) ;-)
Better call the i_one, i_two, i_three, i_four, etc.
Makes your code much more readable, portable, maintainable, etc.
:-)
HansM
the two most popular C compilers for the mac have the following data sizes:
short int long
THINK C 2 bytes 2 bytes 4 bytes
MPW C 2 bytes 4 bytes 4 bytes
Pascal Integers are 2 bytes, LongInts are 4. (the toolbox is written
for pascal)
in order to keep things compatable across compilers, plain ints
are never used.
--
rh...@ic.sunysb.edu Never choose a college because it has a duckpond.
>:-)
>HansM
NO! The ANSI standard should specify that you have to call them:
First_Loop_Control_Variable, Second_Loop_Control_Variable, etc.
:)
--
--------------------------------------------------------------------
******* Tim Hollebeek ==> thol...@ursa.calvin.edu *******
Screw up your courage! You've screwed up everything else.
Why would you use a long when a short would suffice. If your reading a file
in 80 byte increments would you declare a 5000 byte string to hold the data.
> Why would you EVER use NUMBERS in a program.
Maybe you had to support multiple versions of functions in one program, don't
flame me in this it is just a thought; a function that complies to some
standard name ieeeblah().
Basically your problem is that the coder used a short int without realizing
that it only has two bytes and could only store -32768 to 32767. It wasn't a
problem with the types. That's like saying I used a byte and I didn't realize
that it could only hold 256 values. Besides you could have made it unsigned
and increased the size.
--
Robert John Andersen
(919) 380-6523 (v,w)
andersen%rea...@glv.com - NeXT mail!
Outside of a dog, a book is man's best friend.
Inside of a dog it's too dark to read.
Well, I use short ints for two reasons:
1) I know how big they are on each machine I use. The fact that a short is
the same size on 680x0 and 80x86 machines is helpful, whereas ints are
different. This is important when porting code between these two
architectures.
2) The compiler documentation says that array indexing is quicker with
short ints (even though the natural int size is the same as a long).
I think it really depends on whether the processor has optimal instructions
for handling half-word data.
--
_ |__ Alex Matulich alex.m...@oau.org
/(+__> Unicorn Research Corp, 4621 N Landmark Dr, Orlando, FL 32817
//| \ UUCP: al...@bilver.uucp {peora|ge-dab|uunet!tous}!bilver!alex
///__) Internet: al...@bilver.oau.org | alex%bil...@peora.sdc.ccur.com
I agree that short ints are antiquated and generally counterproductive except
when packing data. But I appreciate having the automatic onvversion routines
among 1, 2, and 4 byte integers built into C, because sometimes, I pack data.
>In a related conversation, someone mentioned that many organizations have
>coding standards that let them redefine the size of ints to keep this
>from happening. For instance use int1, int2 and int4 as typedefs and you
>can make them whatever you want. This is where the thought struck me that
>makes me curious to get other peoples' opinion on. Why would you EVER
>use NUMBERS in a program.
The C bug which you encountered is a perfect example of the need for INT2s
and INT4s. Because most PLs don't specify IN or OUT variables using subranges,
the programmer cannot know how large a data structure is needed to hold return
values. As such, the data type MUST match that specified by the function call
prototype (if it exists). Because dissimilar architectures often have different
names for 2 byte ints, you will find the function prototypes differing from
machine to machine. The only way I know to produce code which is portable
across their C libraries is to describe argument variables as being of sizes
which match each architecture's prototypes with a minimum of re-editing. How
better to do that than embed the integer size in the type name (INT2, INT4,
UINT2, UINT4, ...)?
--
Randy
craw...@mitre.org
--
| Randy Crawford craw...@mitre.org The MITRE Corporation
| 7525 Colshire Dr., MS Z421
| N=1 -> P=NP 703 883-7940 McLean, VA 22102
Well, there are really several reasons...
Oh, but of course you were kidding! Never mind.
Michael
--
Michael_...@afs.com
~18 kyu
Q16
NeXTMail appreciated
They use to do this in Fortran. (Actually, they still do, but I'm
trying hard to forget that dark part of my life ;-) The problem is
the assumption that vendor x will make an exact substitution of types
from vendor y, for example, for every function that vendor x specifies
INT2 for, vendor y will specify INT4, but the choice is made on a
function by function basis.
Careful usage is to identify the return type of each function as
'function_return_t', and to use that type appropriately,
including explict casts, and to force the vendor to provide a header
including the correct typedef for function_return_t. Of course,
if a lot of functions are returning a similar thing (ie, they all
return kernel_error_t) then they all get to use the same return type.
Complete usage is for you to do the same thing. You need to figure
out 'classes' that each of your variables belong to and to generate
typedef type names for each 'class' and then to always declare
variables to be of the correct 'class.' (This 'class' has nothing to
do with OO programming.)
Unfortunately, after you've done all of this, you have a program in
which you can easily identify the integer storage size requirements in
all cases -- except 2: Constants, and scanf/printf arguments.
This whole thing is going to get even uglier when you can find usable
64 bit integers and two different sizes of pointers on more machines
than just Crays. (To see the two sizes of poitners problems, program
a pc in pc-C...)
Marty
|> --
|> Randy
|> craw...@mitre.org
|> --
|>
|> | Randy Crawford craw...@mitre.org The MITRE Corporation
|> | 7525 Colshire Dr., MS Z421
|> | N=1 -> P=NP 703 883-7940 McLean, VA 22102
--
Martin Fouts | M/S 1U-14
Member of Technical Staff | HP Laboratories
EMAIL: fo...@hpl.hp.com ! MAIL: P.O. Box 10490
PHONE: (415) 857-2971 | SHIP: 1501 Page Mill Road
FAX: (415) 857-8526 | Palo Alto, CA 94304-1126
novae erratae!
>The problem I started thinking about is WHY IN THE WORLD WOULD ANYONE
>USE SHORT INTS IN A PROGRAM, particularly one done for a workstation-level
>machine (i.e., large memory model, etc).
I agree...I once wrote on our "communal whiteboard" here
"UNSIGNED LONG <EVERYTHING>". I only make things of a different
type when they need to be (ie, something needs to be negative).
>In a related conversation, someone mentioned that many organizations have
>coding standards that let them redefine the size of ints to keep this
>from happening. For instance use int1, int2 and int4 as typedefs and you
>can make them whatever you want. This is where the thought struck me that
>makes me curious to get other peoples' opinion on. Why would you EVER
>use NUMBERS in a program. Except in TWO places: inside quoted strings
>and on the right side of #defs (or the equivalent depending on the
>language). There is no justification for using a number in a variable
>name or typedef or whatever. The above example should be vsi, si and li
>or shint, regint, lngint or something like that. JUST NAMES, NOT NUMBERS.
>Why? Because using numbers causes a confusion in the event that you
>decide to change the platform or the concept. It is fair to say that
>a lngint must be equal to or longer than a regint, but I contend it is
>erroneous and misleading to say that an int4 must be EQUAL TO or longer
>than an int2. Longer than, maybe, but EQUAL TO? That is just wrong.
>In fact, int4 and int2, by normal thought processes, expresses an exact
>2:1 relationship. And the fact that I can change that in a hidden way
>does NOT make things clearer, it makes things muddier.
I don't agree with this at all however...take the following:
typedef char char8;
typedef unsigned char uchar8;
typedef char int8;
typedef unsigned char uint8;
typedef short int int16;
typedef unsigned short int uint16;
typedef long int int32;
typedef unsigned long int uint32;
typedef int intn;
typedef unsigned int uintn;
typedef float float32;
typedef double float64;
This is from a header file from HDF (Hierarchical Data Format), which
is a fairly widely used cross-platform file format used for storing
large amounts of scientific data. The above typedef's are for an
HP-9000, and there are other sets of typedef's for about a dozen
other platforms. You'll notice the "intn" in the middle. This is
only used when you REALLY don't care how long the int is (very seldom).
Can you think of another BETTER way to do this such that the same code
can be used on all of the following platforms AND produce the exact
same files that can be moved transparently from one to the other?
Platform Machine Type
-------- ------------
Sun-4 SUN
Cray-2 UNICOS
Cray-Y/MP UNICOS
Convex CONVEX
SGI Iris 4D IRIS4
IBM RS/6000 IBM6000
DECstation 3100 MIPSEL
DECstation 5000 MIPSEL
Vax/VMS VMS
HP 9000 HP9000
NeXT NEXT
Macintosh MAC
IBM PC/clone PC
Oh, and don't forget, the VAX and PC's have wierd byte ordering :o).
--
Tim McClarren | "...a bajillion brilliant Jobsian lithium licks."
ti...@ncsa.uiuc.edu|
(217)244-0015 |
>(1) It is generally a mark of weak programming
>(2) It is generally poor practice
>(3) It is *always* poor practice
Sigmund Freud had a name for people who think like the above, and
its not very pretty: Anal Retentive.
Doug McDonald
>(2) It is generally poor practice to use numeric constants (other than
>0, 1, occasionally 2, and [*very* rarely] certain bit masks) in the
>body of program code.
How about the following:
GMST = 24110.54841 + (8640184.812866 + (0.093104 - 6.2e-6 * Tu) * Tu) * Tu;
which is the equation for the relationship between Greenwich mean sidereal
time and Universal time. (or was in 1985). I could also post the equation
for the nutation of the Moon, which has 19 terms. Surely you don't expect
someone to define constants for each of them...
--
Marc Kaufman (kau...@CS.Stanford.EDU)
I would guess that if you were writing a program with this expression, you
would be likely to need these numbers again. Even if you didn't need
them anywhere else, constants would be nice. Or better yet, since these
numbers had to come from some equation, probably other than this one,
compute them from more basic numbers like the length of the sidereal year
in seconds. (Plus, of course, a user entered value like the number of
leap seconds added so far this year. :) But I would never use numbers
like these as literal constants. 0, 1, 2, and traditional values like
XSub1, YSub1, XSub2, and YSub2 (for a distance formula) are as far as I go.
Of course, I don't know the meaning of the values in this expression
(since someone forgot to comment them! :), so I could be wrong.
Still, they shouldn't be in the program statements like that.
--
+----------------------------------------------+
|jcas...@nyx.cs.du.edu |
| 186,000 miles per second: |
| It's not just a good idea; it's the law. |
Your quote is completely out of context, and your conclusion is ludicrous.
Just about everything that Geoff Kuenning said was spot-on.
He preceded his advice with the words
|| All of the following statements are guidelines; there will always be
|| exceptions to them:
I have *never* seen programmers use named constants in a situation where
they should obviously be using literals, but I have seen the converse
error *far* too many times.
--
Fergus Henderson f...@munta.cs.mu.OZ.AU
This .signature virus is a self-referential statement that is true - but
you will only be able to consistently believe it if you copy it to your own
.signature file!
And the answer to that is: Ziggy Freud didn't program computers.....
the commentary accompanying the above statements are quite
defensible.....so possibly it's not Goeff who quite so anal....retentive.
Steve
---
+------------------------------------------------------------------+
| In person: Steve Modena AB4EL |
| On phone: (919) 515-5328 |
| At e-mail: nmo...@unity.ncsu.edu |
| samo...@csemail.cropsci.ncsu.edu |
| [ either email address is read each day ] |
| By snail: Crop Sci Dept, Box 7620, NCSU, Raleigh, NC 27695 |
+------------------------------------------------------------------+
Lighten UP! It's just a computer doing that to you.
OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
>In article <kaufman....@Xenon.Stanford.EDU> kau...@CS.Stanford.EDU writes:
>>How about the following:
>>
>>GMST = 24110.54841 + (8640184.812866 + (0.093104 - 6.2e-6 * Tu) * Tu) * Tu;
>>
>>which is the equation for the relationship between Greenwich mean sidereal
>>time and Universal time. (or was in 1985). I could also post the equation
>>for the nutation of the Moon, which has 19 terms. Surely you don't expect
>>someone to define constants for each of them...
>I would guess that if you were writing a program with this expression, you
>would be likely to need these numbers again. Even if you didn't need
>them anywhere else, constants would be nice. Or better yet, since these
>numbers had to come from some equation, probably other than this one,
>compute them from more basic numbers like the length of the sidereal year
>in seconds. (Plus, of course, a user entered value like the number of
>leap seconds added so far this year. :) But I would never use numbers
>like these as literal constants. 0, 1, 2, and traditional values like
>XSub1, YSub1, XSub2, and YSub2 (for a distance formula) are as far as I go.
>Of course, I don't know the meaning of the values in this expression
>(since someone forgot to comment them! :), so I could be wrong.
>Still, they shouldn't be in the program statements like that.
>--
OK look at this, which, like the nutation of the moon, is a better example:
#include <math.h>
#include "astro.h"
/* ....jupiter */
p_jupiter (t, s, dml, ds, dm, da)
double t, s;
double *dml, *ds, *dm, *da;
{
double dp;
double x1, x2, x3, x4, x5, x6, x7;
double sx3, cx3, s2x3, c2x3;
double sx5, cx5, s2x5;
double sx6;
double sx7, cx7, s2x7, c2x7, s3x7, c3x7, s4x7, c4x7, c5x7;
aux_jsun (t, &x1, &x2, &x3, &x4, &x5, &x6);
x7 = x3-x2;
sx3 = sin(x3);
cx3 = cos(x3);
s2x3 = sin(2*x3);
c2x3 = cos(2*x3);
sx5 = sin(x5);
cx5 = cos(x5);
s2x5 = sin(2*x5);
sx6 = sin(x6);
sx7 = sin(x7);
cx7 = cos(x7);
s2x7 = sin(2*x7);
c2x7 = cos(2*x7);
s3x7 = sin(3*x7);
c3x7 = cos(3*x7);
s4x7 = sin(4*x7);
c4x7 = cos(4*x7);
c5x7 = cos(5*x7);
*dml = (3.31364e-1-(1.0281e-2+4.692e-3*x1)*x1)*sx5+
(3.228e-3-(6.4436e-2-2.075e-3*x1)*x1)*cx5-
(3.083e-3+(2.75e-4-4.89e-4*x1)*x1)*s2x5+
2.472e-3*sx6+1.3619e-2*sx7+1.8472e-2*s2x7+6.717e-3*s3x7+
2.775e-3*s4x7+6.417e-3*s2x7*sx3+
(7.275e-3-1.253e-3*x1)*sx7*sx3+
2.439e-3*s3x7*sx3-(3.5681e-2+1.208e-3*x1)*sx7*cx3;
*dml += -3.767e-3*c2x7*sx3-(3.3839e-2+1.125e-3*x1)*cx7*sx3-
4.261e-3*s2x7*cx3+
(1.161e-3*x1-6.333e-3)*cx7*cx3+
2.178e-3*cx3-6.675e-3*c2x7*cx3-2.664e-3*c3x7*cx3-
2.572e-3*sx7*s2x3-3.567e-3*s2x7*s2x3+2.094e-3*cx7*c2x3+
3.342e-3*c2x7*c2x3;
*dml = degrad(*dml);
*ds = (3606+(130-43*x1)*x1)*sx5+(1289-580*x1)*cx5-6764*sx7*sx3-
1110*s2x7*sx3-224*s3x7*sx3-204*sx3+(1284+116*x1)*cx7*sx3+
188*c2x7*sx3+(1460+130*x1)*sx7*cx3+224*s2x7*cx3-817*cx3+
6074*cx3*cx7+992*c2x7*cx3+
508*c3x7*cx3+230*c4x7*cx3+108*c5x7*cx3;
*ds += -(956+73*x1)*sx7*s2x3+448*s2x7*s2x3+137*s3x7*s2x3+
(108*x1-997)*cx7*s2x3+480*c2x7*s2x3+148*c3x7*s2x3+
(99*x1-956)*sx7*c2x3+490*s2x7*c2x3+
158*s3x7*c2x3+179*c2x3+(1024+75*x1)*cx7*c2x3-
437*c2x7*c2x3-132*c3x7*c2x3;
*ds *= 1e-7;
dp = (7.192e-3-3.147e-3*x1)*sx5-4.344e-3*sx3+
(x1*(1.97e-4*x1-6.75e-4)-2.0428e-2)*cx5+
3.4036e-2*cx7*sx3+(7.269e-3+6.72e-4*x1)*sx7*sx3+
5.614e-3*c2x7*sx3+2.964e-3*c3x7*sx3+3.7761e-2*sx7*cx3+
6.158e-3*s2x7*cx3-
6.603e-3*cx7*cx3-5.356e-3*sx7*s2x3+2.722e-3*s2x7*s2x3+
4.483e-3*cx7*s2x3-2.642e-3*c2x7*s2x3+4.403e-3*sx7*c2x3-
2.536e-3*s2x7*c2x3+5.547e-3*cx7*c2x3-2.689e-3*c2x7*c2x3;
*dm = *dml-(degrad(dp)/s);
*da = 205*cx7-263*cx5+693*c2x7+312*c3x7+147*c4x7+299*sx7*sx3+
181*c2x7*sx3+204*s2x7*cx3+111*s3x7*cx3-337*cx7*cx3-
111*c2x7*cx3;
*da *= 1e-6;
}
Considering the name of the subroutine, you can guess pretty well what they
are for. They are the lowest terms in the series expansion for the orbit of
Jupiter.
They come from a standard theory that is decades old. It is not going
to change, ever. If, for some reason, such as a perturbing star passing
nearby, the orbit changes, it's going to need a new theory.
Any names you give to these terms are going to be about as meaningful as
the ones I have assigned to the temporary variables. Sure, I could
assign more verbose names to those variables .... but who cares. The
meaning of the variables in the subroutine parameters are indeed
documented in the calling routine.
Oh yes. This is the **simplified** version. And there are several more
planets. We're talking about whole books of constants: Astronomical Formulae
for Calculators by Jean Meeus. Richmond, Va., U.S.A., Willmann-Bell,
1982 and Astronomy with your Personal Computer by Dr. Peter Duffett-
Smith, Cambridge University Press, 1985.
Frankly, I'm not worried about what to call them or that they are hard
coded. I was **seriously** worried that they were wrong until I verified
the output versus published values. If they are wrong, it is within
the noise of my output and/or the published values are wrong too.
Doug McDonald
In article <kaufman....@Xenon.Stanford.EDU> kau...@CS.Stanford.EDU writes:
>How about the following:
>
>GMST = 24110.54841 + (8640184.812866 + (0.093104 - 6.2e-6 * Tu) * Tu) * Tu;
>
>which is the equation for the relationship between Greenwich mean sidereal
>time and Universal time. (or was in 1985). I could also post the equation
>for the nutation of the Moon, which has 19 terms. Surely you don't expect
>someone to define constants for each of them...
#define GtoU(T) \
((24110.54841 + (8640184.812866 + (0.093104 - 6.2e-6*(T))*(T))*(T))
...
GMST = GtoU(Tu);
...
GMST2 = GtoU(Tu2); /* Assuming there's multiple uses of GtoU */
...
etc.
that's one of a million different way I'd handle it. Which way I actually
choose would depend on the context where this particular piece of code was
located.
Maybe you could show us the entire source?
Anyway, it said it was appropriate to have exactly 3 numbers in your program:
zero, one, and many.
--
Essentia non sunt multiplicanda praeter necessitatum -- William of Ockham
(Fact need not be multiplied beyond necessity)
Someone pointed out to me in one of the MANY MANY (thank you all very
much :-) posts I have received on my obviously controversial position,
that many formulae are simply best expressed in their native numerical
form. I agree. I have not done much "application" programming recently
and have not used such formulae in programs in a long time. I would
have no objection where the purpose of using numbers is to clearly
express the problem.
On the other hand, in system software programming, there are very few
formulae where the actual numbers are meaningful (and more importantly,
are always constant). The few situations generally involve 0 or 1 and
I think I have come to agree that using those numbers, particularly to
start loops or indexes, is acceptable. I still resist the idea of
using numbers in the names of variables except where that is accepted
use of the variables (for instance, in geometric programs, I could see
the use of (x1,y1) and (x2,y2) as point representations because this
is common use).
Jon Rosen
(Calculation intensive routine)
>#include <math.h>
>#include "astro.h"
>/* ....jupiter */
>p_jupiter (t, s, dml, ds, dm, da)
...
There's the problem. You could end up using the same routine for every planet
and all the comets, if only the orbital parameters and masses had been
extracted out.
It's a mistake precomputing all the 85 magic numbers in the calculations of
this routine -- that's what the computer is for. Likewise, it's a mistake to
use a source the precomputes those numbers -- those sources are meant for
hand computation. If the author made an error -- highly probable, or you made
an error (or the scanner), the result is a hidden bug.
So you lose (1) reliability, (2) reuseability, and (3) readibility.
There's no reason not to step back to the perturbation theory itself and
write the program directly on the basis of that, integrating the necessary
Fourier Series calculations right into the software itself. You don't need
to precompute Fourier coefficients any more.
The thing that authors prior to the computer age tend to do that's really
bothersome is they actualy expand out all the terms in full until they get
numbers by plugging in the orbital constants. Don't "simplify" those equations
by plugging in the constants, keep them out and let the software do the
calculation directly from the equations instead.
The result will likely be even more clean and concise than the tables
themselves, and on top of that, easily verifiable.
One approach around the calculation bottleneck is to use complex
polynomials -- a language like C++ is ideally suited for this, since you can
reuse the operators +, -, *, /, etc in the software itself after defining your
own classes, such as for vectors, complex numbers or polynomials or otherwise.
Then you won't need to break down the vector equations into components
anymore. You can directly program those nice looking pristine vector
equations into your software and never have to look at components again.
This is something I wrote that does short-term orbital extrapolation.
Apparently this is using 4th order Runge-Kutta extrapolation or maybe even a
predictor-corrector method (I don't have my book handy), and is printing out
the time, radius and velocity vector (in geocentric polar form) once each
second. The D vector appears to be a perturbation simulating a rocket thrust,
which would mean this is giving you a second-by-second snapshot of a launch.
The Add() vector routine could have been written v += t*w (combining vector
addition and scalar multiplication), if this were in C++. The New() routine
would have been written using C++'s memory allocation operator, new.
#include <stdio.h>
#include <math.h>
#include <float.h>
typedef struct { double X, Y; } Vector;
Vector g, v, r, D; double t;
/* v += t*w */
#define Add(v, t, w) ((v).X += (t)*(w).X, (v).Y += (t)*(w).Y)
#define New(v, x, y) ((v).X = (x), (v).Y = (y))
#define GM (4.0E14)
void Gravity(Vector r) { /* g = D - GM r/|r|^3 */
double r2, s, a; Vector n;
r2 = r.X*r.X + r.Y*r.Y; a = GM/r2;
s = sqrt(r2); New(n, r.X/s, r.Y/s);
g = D; Add(g, -a, n);
}
void Update(double dt) { /* t, r(t), v(t) -> t + dt, r(t + dt), v(t + dt) */
Vector v0, vC, r0, rC;
r0 = r; v0 = v;
Gravity(r0); Add(v, dt/6.0, g);
vC = v0; Add(vC, dt/2.0, g); Add(r, dt/3.0, vC);
rC = r0; Add(rC, dt/2.0, vC); Gravity(rC); Add(v, dt/3.0, g);
vC = v0; Add(vC, dt/2.0, g); Add(r, dt/3.0, vC);
rC = r0; Add(rC, dt/2.0, v0); Gravity(rC); Add(v, dt/3.0, g);
vC = v0; Add(vC, dt/2.0, g); Add(r, dt/3.0, vC);
rC = r0; Add(rC, dt, vC); Gravity(rC); Add(v, dt/6.0, g);
t += dt;
}
#define R 6378000.0
#define PI 3.1415926
void Stats(Vector r, Vector v, double t) {
double tR, tV, mR, mV; char Dir;
tR = atan2(r.Y, r.X)*180.0/PI; mR = sqrt(r.X*r.X + r.Y*r.Y);
tV = atan2(v.Y, v.X)*180.0/PI; mV = sqrt(v.X*v.X + v.Y*v.Y);
printf("%7.3f ", t);
printf("%10.3f %5.2f", mR - R, tR);
tV -= (tR - 90.0); Dir = 1;
if (tV < -180.0) tV += 360.0; else if (tV > 180.0) tV -= 360.0;
if (tV < -90.0) Dir = 0, tV = -180.0 - tV;
else if (tV > 90.0) Dir = 0, tV = 180.0 - tV;
printf(" %10.3f %5.2f%c\n", mV, tV, Dir? 'F': 'B');
}
void Thrust(int T0, int T1, double X, double Y) {
int I;
New(D, X, Y);
for (I = T0; I < T1; I++) Update(1.0), Stats(r, v, t);
}
void main(void) {
int I;
t = 0.0;
New(r, 0.0, R), New(v, 500.0, 0.0);
Stats(r, v, t);
Thrust( 0, 150, 0.0, 20.0);
Thrust(150, 335, 40.0, 0.0);
Thrust(335, 10000, 0.0, 0.0);
}
>There's the problem. You could end up using the same routine for every planet
>and all the comets, if only the orbital parameters and masses had been
>extracted out.
>It's a mistake precomputing all the 85 magic numbers in the calculations of
>this routine -- that's what the computer is for. Likewise, it's a mistake to
>use a source the precomputes those numbers -- those sources are meant for
>hand computation. If the author made an error -- highly probable, or you made
>an error (or the scanner), the result is a hidden bug.
You're right, somewhat. However, we still have to get the 85 magic
observations into the program so that we can compute the Fourier series...
>So you lose (1) reliability, (2) reuseability, and (3) readibility.
...
>#define GM (4.0E14)
>void Gravity(Vector r) { /* g = D - GM r/|r|^3 */
> double r2, s, a; Vector n;
^^ clearely this should be r_squared (use of '2' is forbidden)
> r2 = r.X*r.X + r.Y*r.Y; a = GM/r2;
> s = sqrt(r2); New(n, r.X/s, r.Y/s);
> g = D; Add(g, -a, n);
>}
>void Update(double dt) { /* t, r(t), v(t) -> t + dt, r(t + dt), v(t + dt) */
> Vector v0, vC, r0, rC;
> r0 = r; v0 = v;
> Gravity(r0); Add(v, dt/6.0, g);
^^^ tsk, tsk. What if you were computing this
in another universe with different laws of physics?
> vC = v0; Add(vC, dt/2.0, g); Add(r, dt/3.0, vC);
> rC = r0; Add(rC, dt/2.0, vC); Gravity(rC); Add(v, dt/3.0, g);
> vC = v0; Add(vC, dt/2.0, g); Add(r, dt/3.0, vC);
> rC = r0; Add(rC, dt/2.0, v0); Gravity(rC); Add(v, dt/3.0, g);
> vC = v0; Add(vC, dt/2.0, g); Add(r, dt/3.0, vC);
> rC = r0; Add(rC, dt, vC); Gravity(rC); Add(v, dt/6.0, g);
> t += dt;
>}
>#define R 6378000.0
>#define PI 3.1415926
>void Stats(Vector r, Vector v, double t) {
> double tR, tV, mR, mV; char Dir;
> tR = atan2(r.Y, r.X)*180.0/PI; mR = sqrt(r.X*r.X + r.Y*r.Y);
^^^^^ time to take ANSI to task for using a digit
^^^^^^^^ surely this should have been
#define radians_to_degrees 180.0/PI
> tV = atan2(v.Y, v.X)*180.0/PI; mV = sqrt(v.X*v.X + v.Y*v.Y);
> printf("%7.3f ", t);
^^^ using string concatenation, we can defer the specification
of format widths by placing the 7.3 in a #define
> printf("%10.3f %5.2f", mR - R, tR);
> tV -= (tR - 90.0); Dir = 1;
^^^^ ^ You should use an enum (North, East, South West)
> if (tV < -180.0) tV += 360.0; else if (tV > 180.0) tV -= 360.0;
> if (tV < -90.0) Dir = 0, tV = -180.0 - tV;
> else if (tV > 90.0) Dir = 0, tV = 180.0 - tV;
> printf(" %10.3f %5.2f%c\n", mV, tV, Dir? 'F': 'B');
>}
>void Thrust(int T0, int T1, double X, double Y) {
^^^ ^^^ Don't you remember, it was the size of ints that
started this thread...
> int I;
> New(D, X, Y);
> for (I = T0; I < T1; I++) Update(1.0), Stats(r, v, t);
>}
>void main(void) {
> int I;
> t = 0.0;
> New(r, 0.0, R), New(v, 500.0, 0.0);
> Stats(r, v, t);
> Thrust( 0, 150, 0.0, 20.0);
> Thrust(150, 335, 40.0, 0.0);
> Thrust(335, 10000, 0.0, 0.0);
^^^ in the old days, we read these values in from a data file
rather than embedding them in the program. That way you don't have to
recompile just to get a new value.
>}
--
Marc Kaufman (kau...@CS.Stanford.EDU)
I have no complaints about your constants or your variable names, per se.
Particularly if you are implementing a formula taken directly from the math
in a standard reference, it makes sense to retain the original variable names
from the reference, assuming you have a comment refering the reader to the
reference.
But since you are using both variable names which contain digits ("s2x5"),
and constants which contain both letters and operators ("1.208e-3") --
<begin shouting>
COULD YOU KINDLY SEPARATE CONSTANTS, OPERATORS AND VARIABLES WITH WHITESPACE
SO SOMEBOBY CAN READ IT?
<end shouting>
Thank you.
--
Alan Jeddeloh W:(503) 685-2991 H:(503) 292-9740
Tektronix, Inc. D/S 60-850; PO Box 1000; Wilsonville, OR 97070
Alan.J...@tek.com Let sleeping dogs^H^H^H^Hbabies lie
You can put the children to bed, but you can't make them sleep!
In this day and age, I am disappointed to see people clinging to an
outworn superstition. I am also also disappointed by ad hominem attacks;
never mind the insults dredged from the vocabulary of a dying religion,
is Kuennin *right*? Will Kuennin's advice help people to become better
programmers or not?
In fact, there is so much trash code around that Kuennin's attitude could
be more worthily described as wanting to _Expel_ the garbage.
--
RMIT policy requires the use of Gender Inclusive Language in all publications
and in all information conveyed to students, staff, and potential job
applicants. Lapses into English are the sole responsibility of the author.
The Constitution of Australia does _not_ guarantee Freedom of Speech.
It is good to give meaningful names to things.
It is even better when the names are truthful.
pi is not 3.1415926; if you round it to 8 digits you get 3.1415927
And why round it to 8 digits? I once ran into serious numeric trouble
in a Macintosh program where the calculations were done in 80 bit arithmetic
but PI had been rounded to 64 bits.
What we really want for things like this is the proposed Ada interface,
where you can say how many "things" there are in a complete circle, e.g.
tR := atan(X => r.X, Y => r.Y, Cycle => 360);
This code fragment is a perfect example of something which deserves to be
named. Myself, I might do
#include <math.h>
#if DEGREE_TRIG_PROVIDED
extern double atan2d(double, double);
...
#else
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#define HALF_CIRCLE_OVER_PI (180.0/PI)
#define atan2d(x, y) (atan2(x,y)*HALF_CIRCLE_OVER_PI)
...
#endif
void Stats(Vector r, Vector v, double t)
{
double tR = atan2d(r.Y, r.X);
...
}
I have often found code for special functions in books and journals that
_would_ be useful except that they have rounded the coefficients and
truncated the series to fit a particular machine, and it doesn't fit mine.
Well, in fact, you are both writing "spaghetti code".
It really should be:
inc(count);
Have a nice day. =)
--
****************************************************************************
David E. Nettles
Internet: da...@gdstech.grumman.com
Grumman Data Systems
I don't understand what point you are trying to make. Your text seem
to be disputing the previous poster's claim, which was that for certain
types of computations, embedding explicit numbers in a program is more
sensible than using defined constants. But at the same time your own
code supports the his position. I see a lot of explicit 360.0's and
180.0's and the like. Wouldn't your own arguments suggest that these
should really be replaced by defined constants too? (Actually, this
isn't a completely unreasonable suggestion. After all, not everybody
works in degrees.)
The point that you made about going back to the original computations,
and not using methods that were designed for human calculation is a
good one. But there are times when this is impractical. For example.
if I needed to compute some odd function that I have never seen before,
If I could go to Abramowitz and Stegun's _Handbook of Mathematical
Functions_ and find an approximation that was guaranteed to have a
certain accuracy over a particular range, it would be a lot faster than
studying the function myself and figuring out how to compute it
directly. In many cases, this would also be much more computationally
efficient than direct calculation.
--
Hubert Yamada * Our hero is called before the alien
yam...@galileo.ifa.hawaii.edu * potentate! Where it becomes clear that
yam...@uhunix.uhcc.hawaii.edu * Spiff is about to be sacrificed to appease
Bitnet: yam...@uhunix.bitnet * the evil god they call "Nollij"!
In article <1992Oct3....@mnemosyne.cs.du.edu> jcas...@nyx.cs.du.edu (John Castner) writes:
>In article <kaufman....@Xenon.Stanford.EDU> kau...@CS.Stanford.EDU writes:
>>GMST = 24110.54841 + (8640184.812866 + (0.093104 - 6.2e-6 * Tu) * Tu) * Tu;
>>which is the equation for the relationship between Greenwich mean sidereal
>>time and Universal time. (or was in 1985). I could also post the equation
>>for the nutation of the Moon, which has 19 terms. Surely you don't expect
>>someone to define constants for each of them...
>
>I would guess that if you were writing a program with this expression, you
>would be likely to need these numbers again. Even if you didn't need
>them anywhere else, constants would be nice. Or better yet, since these
>numbers had to come from some equation, probably other than this one,
I have to agree with Mr. Castner. In fact, he even gave another example
to help prove it, but forgot to remark on it:
>|jcas...@nyx.cs.du.edu |
>| 186,000 miles per second: |
>| It's not just a good idea; it's the law. |
Someday someone might want to change this constant to a more accurate
value, right? Wouldn't it be nice if the constant were specified once
in a location more suitable for constant specifications?
In article <1ao349...@uwm.edu> ma...@csd4.csd.uwm.edu (Mark) writes:
>In article <mcdona...@aries.scs.uiuc.edu> mcdo...@aries.scs.uiuc.edu (J. D. McDonald) writes:
>>OK look at this, which, like the nutation of the moon, is a better example
>
>It's a mistake precomputing all the 85 magic numbers in the calculations of
>this routine -- that's what the computer is for. Likewise, it's a mistake to
>use a source the precomputes those numbers
>
>There's no reason not to step back to the perturbation theory itself and
>write the program directly on the basis of that, integrating the necessary
>Fourier Series calculations right into the software itself. You don't need
>to precompute Fourier coefficients any more.
I have to agree with Mark too. After all, look at this:
>#include <math.h>
>#include <float.h>
>typedef struct { double X, Y; } Vector;
[...]
>#define R 6378000.0
>#define PI 3.1415926
It's a mistake to precompute this too, especially when 3.1415927 would be
slightly more accurate than 3.1415926. Shouldn't you include code to
compute PI as accurately as possible?
> tR = atan2(r.Y, r.X)*180.0/PI; mR = sqrt(r.X*r.X + r.Y*r.Y);
Or better yet, to compute 180.0/PI as accurately as possible?
In article <1992Oct4....@organpipe.uug.arizona.edu> da...@cs.arizona.edu (Dave Schaumann) writes:
>Hmm... perhaps it was in _Elements of Programming Style_?
>Anyway, it said it was appropriate to have exactly 3 numbers in your program:
>zero, one, and many. ---
---
Exactly how many numbers, did you say? Uh, suppose I want to write a program
to read your program and check on how many numbers your program has? :-)
--
Norman Diamond dia...@jit081.enet.dec.com
If this were the company's opinion, I wouldn't be allowed to post it.
"Yeah -- bad wiring. That was probably it. Very bad."
I've heard of something stupider. Started off much as above,
#define FOUR 4
After some time, a major change was made, line had to change to
#define FOUR 5
:-)
Ben
As I explained to Norman in a letter, at least in the SI system,
that's no longer a possibility. The speed of light has been fixed and
the length of the meter is now derived from this constant and the second
which is defined independently. The point is moot in the imperial
system which isn't satisfactorily standardized.
>>#define PI 3.1415926
>
>It's a mistake to precompute this too, especially when 3.1415927 would be
>slightly more accurate than 3.1415926. Shouldn't you include code to
>compute PI as accurately as possible?
Hmmph. I like to compute my own constants as much as possible, but
this sort of thing is dangerous. At the very least you would have to
make sure you do this right (using some sort of series summation method
and doing careful error control, presumably in some exact arithmetic
system). I would not want to rely on the value of PI generated by some
application of inverse trig functions nor would I want to sum a series
for PI in floating point arithmetic. On most machines, this would be
OK, but it's not too hard to find hardware/compiler combinations that
are ridiculously poor at evaluating some functions for extreme values
of the arguments. It is probably best in all but the most unusual of
cases to simply get a well-authenticated value of PI valid to some large
number of digits, type it in once, verify it many times (from
different sources) and use that consistently thereafter.
Marc R. Roussel
mrou...@alchemy.chem.utoronto.ca
> Hmmph. I like to compute my own constants as much as possible, but
>this sort of thing is dangerous. At the very least you would have to
>make sure you do this right (using some sort of series summation method
>and doing careful error control, presumably in some exact arithmetic
>system). I would not want to rely on the value of PI generated by some
>application of inverse trig functions nor would I want to sum a series
>for PI in floating point arithmetic. On most machines, this would be
>OK, but it's not too hard to find hardware/compiler combinations that
>are ridiculously poor at evaluating some functions for extreme values
>of the arguments. It is probably best in all but the most unusual of
>cases to simply get a well-authenticated value of PI valid to some large
>number of digits, type it in once, verify it many times (from
>different sources) and use that consistently thereafter.
Using a large number system I took a long decimal value of PI (the system
worked directly in decimal) and multipled it by 2 several times to get the
value of PI multiplied by 2 raised to some high power. I saved the whole
part of this number. When I need PI, I express it as that whole number
(in an appropriate floating point form) divided by that same power of 2.
This usually causes the least damage to the precision of the number.
It often works more accurately than some decimal conversions of fractional
quantities.
--
/***********************************************************************\
| Phil Howard --- KA9WGN --- p...@netcom.com | "The problem with |
| depending on government is that you cannot depend on it" - Tony Brown |
\***********************************************************************/
There are software tools that give more precision than that available
in hardware. The arbitrary precision calculator utility `bc' that is
available on Unix systems, for example, can perform floating point
calculations with precision up to 56 decimal digits.
I think results obtained from inverse tangent routines written in the `bc'
language would be reliable enough for use even with double precision floating
point in compiled code.
I am running the command `bc -lm' with the following input lines,
where a(x) is the arctangent function.
scale = 56 ;
4*a(1);
and here is the result, which is supposed to be close to pi
up to 56 decimal points:
3.14159265358979323846264338327950288419716939937510582096
and with scale set to 99 we obtain:
3.141592653589793238462643383279502884197169399375105820974944592307816\
406286208998628034825342117060
The difference shows up at the 56'th digit after the decimal point, which
is the last significant digit in the first example. IMHO, it would be safe
to round the last digit off.
You can authenticate these values (or your compiler/math library/(FP hardware),
whichever you doubt most ;-) ) by writing simple test programs
with maximum available FP precision. I suppose you can also use sources like
CRC Mathematical Tables for more digits of pi after the decimal point.
The routine for a(x) in the math library file (/usr/lib/lib.b) of `bc'
uses series summation. The same library, accessed by using the `-lm' option,
also provides Bessel, Exponential, Logarithm, Sine and Cosine functions.
User defined functions can be defined in a script file or on the fly, using
single-character identifiers an a familiar, C-like syntax. Finally,
`bc' implements floating point arbitrary precision in *software*,
so the results should be machine-independent.
Yours respectfully,
--
Mustafa KOCATURK mus...@seas.smu.edu Electrical Engineering Department
Home:(214)706-5954 Work:(214)692-2541 SMU Box 753190, Dallas, TX 75275-3190
>There are software tools that give more precision than that available
>in hardware. The arbitrary precision calculator utility `bc' that is
>available on Unix systems,
:-) :-) ;-)
Historical post warning!!!
**************************************************************************
You could also use the IBM 1620, which allowed operating on words up
to 20,000 decimal digits long, fixed or float. (Not exactly in "hardware"
since it didn't **have** adder or multiplier hardware, but nevertheless
could add and multiply words that long in a single instruction.)
I calculated "e" to 9000 digits once, programming the machine in machine
language (not assembler) and it chugged out the answer correctly.
Doug McDonald
How do you know? :-)
Mike Mitten - pdo...@emory.edu - Irony is the spice of life. - DoD#522
I do not speak for Emory University, nor for Public Domain, Inc.