unsigned int assigned to double yields negative # ... Why?

Chris Torek chris at mimsy.UUCP
Sat Mar 19 00:41:06 AEST 1988


In article <5020 at nsc.nsc.com> andrew at nsc.nsc.com (Andrew Lue) writes:
[a buggy example, but I know what the problem is]

Old versions of Vax PCC convert `unsigned' to `float' or `double' with

	cvtl[fd] src, dst

which is just wrong; the conversion should never produce a negative
float or double.  A surprising number of compilers have had the same
bug.  Donn Seeley has fixed this in recent versions of the 4BSD
compilers.  The 4.3BSD compiler turns

	main(){
		register unsigned u = 0xf0000000;
		register float f = u;
		printf("%u %u\n", u, (unsigned)f);
	}

into

	movl	$-268435456,r11		# u = 0xf0000000;
	movl	r11,r10			# begin f = u:
	jbsc	$31,r10,L99999		# was it negative?
	cvtlf	r10,r10			# it was not negative; convert
	jbr	L99998			# and done
L99999:
	cvtlf	r10,r10			# it was negative but is no longer
	addf2	$0f2.147483648e9,r10	# so convert and add 1<<31.
L99998:
	cvtfl	r10,-(sp)		# convert f to [unsigned] int & push
	pushl	r11			# push u
	pushal	L17			# push the format
	calls	$3,_printf		# printf()
	ret

Incidentally, the compiler distributed with 4.3BSD still goofs on
constants:

	double d = (unsigned)0xffffffff;

sets `d' to -1, rather than 2^32 - 1.  (This is already fixed in
later versions.)
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris at mimsy.umd.edu	Path:	uunet!mimsy!chris



More information about the Comp.lang.c mailing list