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