why still use C?

M

Mike Cowlishaw

OK, so still between 49.8 and 53.1 equivalent bits for the mantissa,
11.3 bits for the exponent, and 1 for the sign, so 62.1 worst case
and 65.4 best case, for 63.75 average case, or 99.6% efficient.

This reminds me of all the work the authors of the original Fortran
compiler did to generate as efficient object code as possible.
They needed to convince people that Fortran could be used in place
of assembly code, without a significant loss of efficiency.

Personally, I would have been happy with ordinary BCD arithmetic,
in floating point form. It seems to have worked well for calculator
users for many years now.

There are a few constraints, though. For example, the ISO
COBOL 2002 standard specifies that intermediate calculations
be done using 32 decimal digits of precision. 32 digits of BCD
into a 128-bit register leaves very little room for a sign and
exponent.

Mike Cowlishaw
 
D

Douglas A. Gwyn

Kalle Olavi Niemitalo said:
Type checks like this would be easier if the comma operator were
allowed in constant expressions.

Yes; that's an aggravating restriction.
The main argument for it seems to be to diagnose
int a[20,30];
but with VLAs that has to be allowed anyway in many contexts,
so it seems pointless to keep the restriction.
 
D

Douglas A. Gwyn

Arthur J. O'Dwyer said:
and I'm curious as to what various compilers make of 'sizeof(1/0)',
and whether it's valid C or not. [I think the answer should be
sizeof(int), but I'm not sure it doesn't invoke UB.]

There is no undefined behavior, because the / operator is not
executed (the argument of sizeof is not evaluated).
 
P

Paul Eggert

Kalle Olavi Niemitalo said:
Type checks like this would be easier if the comma operator were
allowed in constant expressions.

Yes; that's an aggravating restriction.
The main argument for it seems to be to diagnose
int a[20,30];

A diagnostic for that declaration is required regardless of whether
commas are allowed in constant expressions. This is because a
direct-declarator (which is used to declare array types and their
bounds) must contain an assignment-expression, and
assignment-expressions must not contain a comma at the top level.
Seethe syntax in C99 section 6.7.5.

I think it's a good idea to have a diagnostic for that declaration, as
it's an understandably common error for C neophytes. But this issue
is independent of whether the comma operator should be allowed in
constant expressions.
 
C

CBFalconer

Mike said:

Thanks for the references. I am convinced as to the packing and
convertability, but offhand I don't think it solves the
normalization problem. It will still be necessary to normalize to
base 1000, or to convert to BCD and normalize to base 10, with the
effective loss of 4 to 10 bits of precision as compared to binary.

i.e. the minimum normalized value in Chen-Ho encoding and 30 bits
is 1,000,000 while the minimum in binary is 2**29, or about
500,000,000. This is ameliorated by the need for less bits to
describe the exponent to cover the same magnitudes. We haven't
even considered the efficiency improvement of assumed leading 1
bits in binary.

USE worldnet address!
 
G

glen herrmannsfeldt

Mike Cowlishaw wrote:

(snip)
There are a few constraints, though. For example, the ISO
COBOL 2002 standard specifies that intermediate calculations
be done using 32 decimal digits of precision. 32 digits of BCD
into a 128-bit register leaves very little room for a sign and
exponent.

I still have never written a COBOL program, but is that fixed point or
floating point?

-- glen
 
G

glen herrmannsfeldt

CBFalconer wrote:
(snip)
Thanks for the references. I am convinced as to the packing and
convertability, but offhand I don't think it solves the
normalization problem. It will still be necessary to normalize to
base 1000, or to convert to BCD and normalize to base 10, with the
effective loss of 4 to 10 bits of precision as compared to binary.

One possibility is to store them in the registers in BCD.

Another is to convert to BCD, perform arithmetic operations, and
convert back to the packed form. This might be needed if the
same registers were used, and it was necessary not to enlarge
them. Though the Intel 80 bit registers should be big enough.
i.e. the minimum normalized value in Chen-Ho encoding and 30 bits
is 1,000,000 while the minimum in binary is 2**29, or about
500,000,000. This is ameliorated by the need for less bits to
describe the exponent to cover the same magnitudes. We haven't
even considered the efficiency improvement of assumed leading 1
bits in binary.

The calculation I did some days ago included the hidden bit.

Or at least I meant it to. IEEE double is 53 bits, including the
hidden 1.

-- glen
 
M

Mike Cowlishaw

There are a few constraints, though. For example, the ISO
I still have never written a COBOL program, but is that fixed point or
floating point?

'Standard' COBOL arithmetic. Calculate as well as possible and then
assign to a fixed-point variable. Best ask COBOL folk what that is :).

Mike
 
M

Mike Cowlishaw

(snip of base 1000 representation of decimal floating point)
Thanks for the references. I am convinced as to the packing and
convertability, but offhand I don't think it solves the
normalization problem. It will still be necessary to normalize to
base 1000, or to convert to BCD and normalize to base 10, with the
effective loss of 4 to 10 bits of precision as compared to binary.

Please explain the 'normalization problem' ... I have tried to
cover that in my FAQ but onviiously am lacking something.
i.e. the minimum normalized value in Chen-Ho encoding and 30 bits
is 1,000,000 while the minimum in binary is 2**29, or about
500,000,000. This is ameliorated by the need for less bits to
describe the exponent to cover the same magnitudes. We haven't
even considered the efficiency improvement of assumed leading 1
bits in binary.

[I think your calculations are a bit off?]

Mike Cowlishaw
 
C

Christian Bau

I still have never written a COBOL program, but is that fixed point or
floating point?

'Standard' COBOL arithmetic. Calculate as well as possible and then
assign to a fixed-point variable. Best ask COBOL folk what that is :).[/QUOTE]

As you say COBOL requires 32 decimal digits of precision. Would that be
_exactly_ 32 digits of precision or _at least_ 32 digits of precision? I
think producing _exactly_ 32 digits if what you have available is 34
digits could be difficult.
 
J

Jerry Feldman

'Standard' COBOL arithmetic. Calculate as well as possible and then
assign to a fixed-point variable. Best ask COBOL folk what that is
:).
COBOL on some mainframes use true BCD arithmetic where each digit is
stored in a nybble with the sign usually taking up a nybble (I worked on
a mainframe where BCD numbers were nybble addresssable and the sign
could be either on the msb or lsb or absent. IBM mainframes, the sign is
in the low order nybble or the LSB. A number could have nearly any
precision and any number of decimal points since is was stored in
consecutive bytes. The hardware suppored this.
 
M

Mike Cowlishaw

There are a few constraints, though. For example, the ISO
As you say COBOL requires 32 decimal digits of precision. Would that
be _exactly_ 32 digits of precision or _at least_ 32 digits of
precision? I think producing _exactly_ 32 digits if what you have
available is 34 digits could be difficult.

I forget the actual wording. The final draft is on the web, somewhere,
if you want to check.

Mike Cowlishaw
 
D

David R Tribble

I forget the actual wording. The final draft is on the web, somewhere,
if you want to check.

This precision requirement could be based on IBM's COBOL arithmetic, which
uses 30 or 31 decimal digits (I don't remember which) for all intermediate
results in fixed-point arithmetic expressions. If any floating-point
values are present in a given expression, the whole thing is done in
floating-point instead.

Anyway, 30 or 31 BCD digits plus a sign nibble fit quite naturally into
128 bits (16 bytes). IBM stipulated additional rules for handling gradual
loss of precision (i.e., truncation of least sigificant digits) for the
arithmetic operators, so that no high-order digits are lost (this differs
from PL/1 semantics).

It just so happens that IBM 360 (370, 390, etc.) hardware directly supports
signed BCD arithmetic of up to 31 digits (as do some other systems, e.g.
VAX).

-drt
 
M

Mike Cowlishaw

David said:
This precision requirement could be based on IBM's COBOL arithmetic,
which uses 30 or 31 decimal digits (I don't remember which) for all
intermediate results in fixed-point arithmetic expressions. If any
floating-point values are present in a given expression, the whole
thing is done in floating-point instead.

Anyway, 30 or 31 BCD digits plus a sign nibble fit quite naturally
into 128 bits (16 bytes). IBM stipulated additional rules for
handling gradual loss of precision (i.e., truncation of least
sigificant digits) for the arithmetic operators, so that no
high-order digits are lost (this differs from PL/1 semantics).

It just so happens that IBM 360 (370, 390, etc.) hardware directly
supports signed BCD arithmetic of up to 31 digits (as do some other
systems, e.g. VAX).

We're talking about COBOL 2002. This specifies 32-digit
intermediate results, not 31. (The conspiracy theorists suggest
that this is so that IBM BCD hardware cannot be used :).)

mfc
 
C

Clark S. Cox III

Maybe you should read the standard. The const keyword is certainly
defined, but it has a different meaning
than in C++. const int foo = 4;
In C, foo is a variable and will be treated as such. int *pf = (int *)&foo;
*pf = x;

You are mistaken. You cannot legally do that in either language.

From the standard:

6.7.3 5
"If an attempt is made to modify an object defined with a
const-qualified type through use of an lvalue with non-const-qualified
type, the behavior is undefined."
 
R

Robert Seacord

Clark,

Comment/question below.
You are mistaken. You cannot legally do that in either language.

From the standard:

6.7.3 5
"If an attempt is made to modify an object defined with a
const-qualified type through use of an lvalue with non-const-qualified
type, the behavior is undefined."

I lifted the following example from c99 6.5.16.1 Simple assignment:

const char **cpp;
char *p;
const char c = 'A';

printf("c = %c.\n", c);

cpp = &p; // constraint violation
*cpp = &c; // valid
*p = 'B'; // valid

printf("c = %c.\n", c);

It compiles without warning on Microsoft Visual C++ .NET (2003) and on
MS Visual Studio 2005. In both cases, the resulting program changes the
value of c.

gcc version 3.2.2 generates a warning but compiles. The resulting
program changes the value of c.

I guess I'm wondering what a constraint violation is. I know a
constraint is defined as a restriction, either syntactic or semantic, by
which the exposition of language elements is to be interpreted.

But doesn't a compliant compiler need to issue a fatal diagnostic for a
constraint violation. Or maybe even a warning?

rCs
 
F

Flash Gordon

[mod note: I received something like 200 submissions of this post, and
there's no contact address for the author. This is the second or third time.
If I can't contact someone, I will happily just add mail filters to deal
with stuff like this. Be contactable. -mod]

Robert said:
Clark,

Comment/question below.


I lifted the following example from c99 6.5.16.1 Simple assignment:

const char **cpp;
char *p;
const char c = 'A';

printf("c = %c.\n", c);

cpp = &p; // constraint violation
*cpp = &c; // valid
*p = 'B'; // valid

printf("c = %c.\n", c);

It compiles without warning on Microsoft Visual C++ .NET (2003) and on
MS Visual Studio 2005. In both cases, the resulting program changes the
value of c.

In that case you need to make sure you are compiling it as C code and
make sure you have told the compiler to follow the C standard. I don't
currently have my Windows notebook with me to test it myself since it
did not catch the same plain as me.
gcc version 3.2.2 generates a warning but compiles. The resulting
program changes the value of c.

The C standard does not mandate that programs fail to compile after
producing and required diagnostics (Warnings, Information messages,
Error, insults about your coding abilities, and of these could be issued
as a "diagnostic"). Also, once undefined behaviour is invoked, the
program is allowed to do anything. One of the infinitely many "any
things" it can do is exactly what you expect. However, tomorrow it might
not change the value of C, or after you upgrade the compiler the
behaviour might change (this does happen to people), or it might decide
to report you to the CIA for spying.
I guess I'm wondering what a constraint violation is. I know a
constraint is defined as a restriction, either syntactic or semantic, by
which the exposition of language elements is to be interpreted.

At its simplest, a constraint violation is where the standard places a
constraint (limitation) on what you are allowed in your code, and you
violate that constraint in your code.
But doesn't a compliant compiler need to issue a fatal diagnostic for a
constraint violation. Or maybe even a warning?

See above. Any form of "diagnostic" message is allowed, even something like:
Write out 1000 time "I will not write code with errors"
The compiler could even just fart in your general direction.

After issuing some form of message the compiler is allowed to continue
to compiler the program (although it does not matter what the program
then does) or reject the program.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top