mcdonald@uxe.cso.uiuc.edu (08/13/88)
> printf ("y: %d -> %lf z: %u -> %lf\n", y, (double) y, z, (double) z); > y++; z++; > printf ("y: %d -> %lf z: %u -> %lf\n", y, (double) y, z, (double) z); I tries this on my IBM-PC with microsoft C 5.1 and of course got garbage. The reason is obvious: %d SHOULD be %ld and %u should be %lu. With these changes, the output, all 4 numbers, are exactly what one would expect for a two's complement integer machine. The problem with the original is that printf picks up the wrong bytes to output, due to the size of the integer arguments not agreeing with the format specifications. Try a corrected program and see what happens. Doug McDonald
chris@mimsy.UUCP (Chris Torek) (08/13/88)
In article <1239500001@osiris.cso.uiuc.edu> olson@osiris.cso.uiuc.edu writes: >... found this problem on Pyramid and Masscomp machines, and not on Sun >machines. The same bug *does* exist in 4.1BSD, and *not* in 4.3BSD (and I am not sure about 4.2BSD). >... casting unsigned long to double ... treat the cast as SIGNED long >to double. Actually, any conversion of u_long to double, regardless of context. > printf ("y: %d -> %lf z: %u -> %lf\n", y, (double) y, z, (double) z); %lf makes no sense here. In K&R C, %f prints a double, since there are no float rvalues. In dpANS C, %lf prints a long double. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
olson@osiris.cso.uiuc.edu (08/15/88)
I muddied the waters using printf ... different machines accept different things... However, we examined the assembly language as compiled, and SUN and PYRAMID compilers assemble differently. The bug is real. I expect the response about which BSD version one has is the key. Our Pyramid has 4.2BSD... and the bug exists there. I received mail from a CONVEX user whose machine compiled incorrectly.
matt@ncr-sd.SanDiego.NCR.COM (Matt Costello) (08/31/88)
In article <1239500001@osiris.cso.uiuc.edu> olson@osiris.cso.uiuc.edu writes: >The problem involves casting unsigned long to double. The Pyramid and >Masscomp compilers treat the cast as SIGNED long to double. If the >value is large enough, you have troubles. The problem has existed in PCC since the beginning, as the PDP-11 did not readily support 32 bit integers. The few double-word instructions, including the floating point conversions, only supported signed values. Neither the VAX nor the M68881 support conversions to or from unsigned values either. The code sequences to handle the unsigned long to double conversion (and vice versa) would have imposed an unacceptable performace penalty, so it wasn't done. I don't have my K&R here, but I don't even believe that unsigned longs were legal back then. -- Matt Costello <matt.costello@SanDiego.NCR.COM> +1 619 485 2926 <matt.costello%SanDiego.NCR.COM@Relay.CS.NET> {ucsd,att,pyramid,nosc.mil}!ncr-sd!matt
chris@mimsy.UUCP (Chris Torek) (08/31/88)
>In article <1239500001@osiris.cso.uiuc.edu> olson@osiris.cso.uiuc.edu writes: [various compilers convert as if from signed long to double] In article <2590@ncr-sd.SanDiego.NCR.COM> matt@ncr-sd.SanDiego.NCR.COM (Matt Costello) writes: >The problem has existed in PCC since the beginning, Probably true (I have not been around long enough to really know; I believe PCC appeared in phototypesetter V6, which I have never used.) >as the PDP-11 did not readily support 32 bit integers. Not a good excuse. I imagine it was simply never tested. >Neither the VAX nor the M68881 support conversions to or from unsigned >values either. Conversion on a VAX is easy: cvtl[fd] src,dst bgeq 0f; add[fd]2 $0[fd]4294967296.0,r2; 0: On a 68000 it would be something longer, but also involve testing the sign before or during conversion. >The code sequences to handle the unsigned long to double conversion >(and vice versa) would have imposed an unacceptable performace penalty, >so it wasn't done. Better slow than wrong. I think it was just an oversight. One could make the claim that unsigned division and modulus on a VAX impose an unacceptable performance penalty (it takes far more than the four instructions above), yet they were done. >I don't have my K&R here, but I don't even believe >that unsigned longs were legal back then. I believe the One True C Compiler (dmr's '11 compiler) :-) did not have unsigned <char, short, long> variants. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
henry@utzoo.uucp (Henry Spencer) (09/08/88)
In article <13315@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes: >I believe the One True C Compiler (dmr's '11 compiler) :-) did not have >unsigned <char, short, long> variants. Well, originally of course it didn't have "unsigned" at all! Unsigned long never did exist in the DMR compiler. Unsigned short sort of existed -- "short" essentially turned into "int" very early, as a quick way of hacking "short" in. Unsigned char wasn't present for a long time, but the System V version did have it -- I don't know whether that was Dennis's work or somebody else's. -- Intel CPUs are not defective, | Henry Spencer at U of Toronto Zoology they just act that way. | uunet!attcan!utzoo!henry henry@zoo.toronto.edu