*BSD News Article 9701


Return to BSD News archive

Received: by minnie.vk1xwt.ampr.org with NNTP
	id AA6316 ; Thu, 07 Jan 93 21:08:14 EST
Path: sserve!manuel.anu.edu.au!munnari.oz.au!sgiblab!spool.mu.edu!uunet!mcsun!uknet!robobar!steve
From: steve@robobar.co.uk (Steve Bleazard)
Newsgroups: comp.unix.bsd
Subject: Re: Doubles rounded when cast to int
Keywords: gcc, floating, integers
Message-ID: <1993Jan09.111911.10313@robobar.co.uk>
Date: 9 Jan 93 11:19:11 GMT
References: <1993Jan6.143337.17276@netcom.com>
Organization: Robobar Ltd., Perivale, Middx., ENGLAND.
Lines: 124

In article <1993Jan6.143337.17276@netcom.com> abe@netcom.com (David Abercrombie) writes:
>Programs compiled on 386bsd using gcc 1.39 do not seem to 
>cast doubles to ints correctly.  K&R says: "When the value of
>a floating type is converted to integral type, the fractional 
>is discarded...".  However, on my system (and on ref.tfs.com under
>gcc 1.39), doubles get _rounded_ to the nearest int during a cast 
>(instead of getting truncated).

I am currently porting the BSD libraries to xenix and have had the same
problem.  The bug appears to be in the __fix{uns}dfsi routines that convert
from double to long.  The 386 versions of these routines do not appear to
set the rounding mode.  Versions of these routines which correctly set and
restore the rounding mode are included at the end of this article.

>Compiling with gcc 2.3.3 (on ref.tfs.com) provides programs 
>that cast doubles to ints properly.
>

gcc 2.3.3 appears to have it's own C version of these routines.

As for copyright, I hearby donate the contents of this file to the Public
Domain. Do as you will, but don't blaim me if it all goes wrong.

Steve
------------------------------ Cut Here ------------------------------
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	fixdfsi.S
#	fixunsdfsi.S
# This archive created: Sat Jan  9 10:34:31 1993
export PATH; PATH=/bin:$PATH
if test -f 'fixdfsi.S'
then
	echo shar: will not over-write existing file "'fixdfsi.S'"
else
sed 's/^X//' << \SHAR_EOF > 'fixdfsi.S'
X	.file	"__fixdfsi.s"
X.text
X	.align 2
X.globl ___fixdfsi
X___fixdfsi:
X	pushl %ebp
X	movl %esp,%ebp
X	subl	$12,%esp
X	fstcw	-4(%ebp)  
X	movw	-4(%ebp),%ax
X	orw	$0x0c00,%ax  
X	movw	%ax,-2(%ebp) 
X	fldcw	-2(%ebp)     
X	fldl	8(%ebp)
X	fistpl	-12(%ebp)    
X	fldcw	-4(%ebp)     
X	movl	-12(%ebp),%eax
X	leave
X	ret
SHAR_EOF
fi # end of overwriting check
if test -f 'fixunsdfsi.S'
then
	echo shar: will not over-write existing file "'fixunsdfsi.S'"
else
sed 's/^X//' << \SHAR_EOF > 'fixunsdfsi.S'
X	.file	"__fixdfsi.s"
X.text
X	.align 2
X.globl ___fixunsdfsi
X___fixunsdfsi:
X	pushl	%ebp
X	movl	%esp,%ebp
X	subl	$12,%esp
X	fstcw	-4(%ebp)  
X	movw	-4(%ebp),%ax
X	orw	$0x0c00,%ax  
X	movw	%ax,-2(%ebp) 
X	fldcw	-2(%ebp)     
X	fldl	8(%ebp)
X
X	fcoml	fbiggestsigned	/* bigger than biggest signed? */
X	fstsw	%ax
X	sahf
X	jnb	1f
X	
X	fistpl	-12(%ebp)    
X	movl	-12(%ebp),%eax
X	jmp	2f
X
X1:	fsubl	fbiggestsigned	/* reduce for proper conversion */
X	fistpl	-12(%ebp)		/* convert */
X	movl	-12(%ebp),%eax
X	orl	$0x80000000,%eax	/* restore bias */
X
X2:	fldcw	-4(%ebp)     
X	leave
X	ret
X
X	fcoml	fbiggestsigned	/* bigger than biggest signed? */
X	fstsw	%ax
X	sahf
X	jnb	1f
X	
X	fistpl	4(%esp)
X	movl	4(%esp),%eax
X	ret
X
X1:	fsubl	fbiggestsigned	/* reduce for proper conversion */
X	fistpl	4(%esp)		/* convert */
X	movl	4(%esp),%eax
X	orl	$0x80000000,%eax	/* restore bias */
X	ret
X
X	.data
Xfbiggestsigned:	.double	0r2147483648.0
SHAR_EOF
fi # end of overwriting check
#	End of shell archive
exit 0
-- 
Steve.Bleazard@RoboBar.Co.Uk        | Phone:  +44 81 991 1142 x153
Snr Software Engineer, Robobar Ltd. | Fax:    +44 81 998 8343 (G3)
22 Wadsworth Road, Perivale.        |
Middx., UB6 7JD ENGLAND.            | ...!uknet!robobar!steve