[net.lang.c] Double->unsigned conversion summary

wendyt@isieng.UUCP (Wendy Thrash) (01/21/86)

Followup-To:

About two weeks ago I posted my large double to unsigned conversion test
program.  This program was motivated by my own attempts to do something
reasonable with a 68020/68881 compiler.  The 68881 is a lovely chip in
some ways.  It makes float/double->int conversions very easy.  Unfortunately,
it has no concept of unsigned (or if it does, I've been too stupid to find it.)
I was trying to decide how much care it was reasonable to take, wondered
what other compiler writers had done.

Many thanks to those who sent replies or posted followups.
My choice for the gold medal is gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>),
who posted a followup, run with SVR2 on an unspecified VAX:

Values		         1 2147483647 2147483648 2147483649 4294967295
Came from	0x00000001 0x7fffffff 0x80000000 0x80000001 0xffffffff
Turn into	0x00000001 0x7fffffff 0x80000000 0x80000001 0xffffffff
Negated, into	0xffffffff 0x80000001 0x80000000 0x7fffffff 0x00000001
Incremented,	0x80000001 0xffffffff 0x00000000 0x00000001 0x7fffffff
Inc. & neg.,	0x7fffffff 0x00000001 0x00000000 0xffffffff 0x80000001

Doug suggests that this seems correct "according to the language rules,"
and I agree. Actually, K&R state that "The result is undefined if the
value will not fit in the space provided."  It may be undefined to the
user, but compiler writers have to set it to SOMETHING.  To me (and,
apparently, to DG) it makes some sense to have double->unsigned conversions
wrap around in the same way as int->char and the like.

Although things are a bit fuzzy, the first three lines seem like the kind
of thing a compiler ought to be able to do as a minimum: take an unsigned,
convert it into a double, get the correct (positive) numerical value,
convert that back into unsigned, and get what you started with.  The fourth
line should also easy, as should the first two columns of the last two lines.

I received results from eight other systems. NONE matched the results
above, and they seldom matched each other.  (I suppose the program should
have done some fflush(stdout) calls for the sake of the 3B-20s. Mea culpa.)
Results can be found at the end of this article.  I also received mail from
Philip Kos (osiris!phil) and Tracey Baker (gatech!vax135!tab), but the
bodies of their messages were somehow stripped, so I have no idea what
they sent. Again, thanks to all.

Ken Turkowski ( {amd,decwrl,hplabs,seismo,spar}!turtlevax!ken ) is the
only one who responded to my question about really large values.
His followup suggests arithmetic exceptions and 0xffffffff when things
get out of hand.  Sounds good, but I still like wraparound as long as
there is any precision left.

Conclusion:  Don't assume that your compiler does what you would expect.
As the guy used to say on Hill Street Blues, "Let's be careful out there."

-------------------------- results follow ----------------------------
Tony Hansen (ihnp4!pegasus!hansen) sent mail with the following results
from an AT&T 3B-20 running System V release 2:
Values                   1 2147483647 2147483648 2147483649 4294967295
Came from       0x00000001 0x7fffffff 0x80000000 0x80000001 0xffffffff
Floating exception - core dumped

Robert Skinner sent the following:

VAX 11/750 with S/W NON-IEEE floating point:

Values		         1 2147483647 -2147483648 -2147483647         -1
Came from	0x00000001 0x7fffffff 0x80000000 0x80000001 0xffffffff
Turn into	0x00000001 0x7fffffff 0x80000000 0x80000001 0xffffffff
Negated, into	0xffffffff 0x80000001 0x80000000 0x7fffffff 0x00000001
Incremented,	0x80000001 0xffffffff 0x00000000 0x00000001 0x7fffffff
Inc. & neg.,	0x7fffffff 0x00000001 0x00000000 0xffffffff 0x80000001

National Semi 32032 with H/W IEEE floating point:

Values		1.0000000000 2147483647 -2147483648 -2147483647 -1.0000000000
Came from	0x00000001 0x7fffffff 0x80000000 0x80000001 0xffffffff
Turn into	0x00000001 0x7fffffff 0x80000000 0x80000001 0xffffffff
Negated, into	0xffffffff 0x80000001 ********** 0x7fffffff 0x00000001
Incremented,	********** ********** 0x00000000 0x00000001 0x7fffffff
Inc. & neg.,	********** ********** 0x00000000 0xffffffff 0x80000001

***** = Floating Point Exception in truncation to integer.

Roger Hayes <pyramid!Shasta!rogerh%arizona.csnet@CSNET-RELAY.ARPA> sent
the following:

Vax/8600 running a beta 4.3: (crt0.c 5.1 (Berkeley) 5/30/85, cc.c 4.13 9/18/85)

Values		         1 2147483647 -2147483648 -2147483647         -1
Came from	0x00000001 0x7fffffff 0x80000000 0x80000001 0xffffffff
Turn into	0x00000001 0x7fffffff 0x80000000 0x80000001 0xffffffff
Negated, into	0xffffffff 0x80000001 0x80000000 0x7fffffff 0x00000001
Incremented,	0x80000001 0xffffffff 0x00000000 0x00000001 0x7fffffff
Inc. & neg.,	0x7fffffff 0x00000001 0x00000000 0xffffffff 0x80000001

Sun-120, running Sun 4.2 version 2.0: (crt0.s 1.1 84/12/20 Copyr 1983 Sun
Micro ...  cc.c 1.1 84/12/20 SMI ...  ecvt.c 1.1 84/12/20 Copyr 1984 Sun
Micro ...  isinf.c 1.1 84/12/20 SMI ...)

Values		         1 2147483647 -2147483648 -2147483647         -1
Came from	0x00000001 0x7fffffff 0x80000000 0x80000001 0xffffffff
Turn into	0x00000001 0x7fffffff 0x80000000 0x80000001 0xffffffff
Negated, into	0xffffffff 0x80000001 0x80000000 0x7fffffff 0x00000001
Incremented,	0x80000000 0x80000000 0x00000000 0x00000001 0x7fffffff
Inc. & neg.,	0x80000000 0x80000000 0x00000000 0xffffffff 0x80000001

"a HP 9040 (?) system we have lying around:" (/bin/cc: 26.1)

Values                   1 2147483647 -2147483648 -2147483647         -1
Came from       0x00000001 0x7fffffff 0x80000000 0x80000001 0xffffffff
Turn into       0x00000001 0x7fffffff 0x80000000 0x80000001 0xffffffff
Negated, into   0xffffffff 0x80000001 0x7fffffff 0x7fffffff 0x00000001
Incremented,    0x7fffffff 0x7fffffff 0x00000000 0x00000001 0x7fffffff
Inc. & neg.,    0x80000000 0x80000000 0x00000000 0xffffffff 0x80000001

"a Ridge-32 running some version of ROS:" (cc.v    1.36    6/7/85)

Values                   1 2147483647 -2147483648 -2147483647         -1
Came from       0x00000001 0x7fffffff 0x80000000 0x80000001 0xffffffff
Turn into       0x00000001 0x7fffffff 0x80000000 0x80000001 0xffffffff
Negated, into   0xffffffff 0x80000001 0x7fffffff 0x7fffffff 0x00000001
Incremented,    0x7fffffff 0x7fffffff 0x00000000 0x00000001 0x7fffffff
Inc. & neg.,    0x80000000 0x80000000 0x00000000 0xffffffff 0x80000001

3B5 running Sys V rel 2.0 version 2:

Illegal instruction - core dumped

gwyn@brl-tgr.UUCP (01/22/86)

> Values		         1 2147483647 2147483648 2147483649 4294967295
> Came from	0x00000001 0x7fffffff 0x80000000 0x80000001 0xffffffff
> Turn into	0x00000001 0x7fffffff 0x80000000 0x80000001 0xffffffff
> Negated, into	0xffffffff 0x80000001 0x80000000 0x7fffffff 0x00000001
> Incremented,	0x80000001 0xffffffff 0x00000000 0x00000001 0x7fffffff
> Inc. & neg.,	0x7fffffff 0x00000001 0x00000000 0xffffffff 0x80000001
> 
> Doug suggests that this seems correct "according to the language rules,"
> and I agree. Actually, K&R state that "The result is undefined if the
> value will not fit in the space provided."  It may be undefined to the
> user, but compiler writers have to set it to SOMETHING.  To me (and,
> apparently, to DG) it makes some sense to have double->unsigned conversions
> wrap around in the same way as int->char and the like.

X3J11 has been a bit more thorough in specifying arithmetic conversions,
and my belief is that the above results agree with what they propose.

> Conclusion:  Don't assume that your compiler does what you would expect.
> As the guy used to say on Hill Street Blues, "Let's be careful out there."

Especially beware of Berkeley-based systems, which often use C compilers
derived from a PCC of approximately USG 3.0 vintage.  That compiler did
not properly propagate types through expressions.  (The same is true of
older Ritchie PDP-11 C compilers.)  Except for the ICON problem reported
some time ago, I have not experienced any unpleasant surprises due to the
SVR2 VAX PCC's interpretation of the C language rules.  One would hope
that PCC2 (which I do not have access to) is as reliable, but after your
posting of the results, this is less certain.  (Surely at least one of
those 3Bs must have used PCC2?)