🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.std.c
Article #3755

Re: Casting float to int - standard bug?

#3755
From: FFarance
Date: Thu, 17 Aug 1995 01:52
100 lines
2921 bytes
> From: seebs@solutions.solon.com (Peter Seebach)
> Newsgroups: comp.std.c
> 
> It is undefined behavior to cast a float into an int, if the value
contained
> in that float is larger than INT_MAX, correct?

Yes, this is undefined behavior.

> How are we to test this?  There exists (on at least one machine) at
least
> one float greater than INT_MAX which compares less than (float) INT_MAX;
> in particular, on a 68000 system I use, INT_MAX is 2147483647, but
> (float) INT_MAX is 2147483648.  So, 2147483647.5 would compare less
> than INT_MAX, but would (in fact) be too large.

It is possible that an "int" may have more precision available than
can be stored in a "long double" (e.g., 128-bit "int", 80-bit "long
double").  The opposite may be true, i.e., "long double" has more
precision than an "int".  Thus, we can't cast one to the other because
we don't know which one is larger.

When converting "float" to "int", you can use:

	frexp(f,&f_bits);
	if ( f_bits < int_bits() )
	{
		i = (int) f;
	}
	else
	{
		/* error */
	}

When converting "int" to "float", you can use:

	if ( int_bits() < float_bits() )
	{
		f = (float) i;
	}
	else
	{
		/* error */
	}

The helper functions are:

	int int_bits()
	{
		int bit_count;
		unsigned int bits;

		bit_count = 0;
		bits = 0;
		bits--;

		/*
		 * Counting bits is more reliable than multiplying
		 * "CHAR_BIT" by "sizeof(int)" because the "int"
		 * may have ``holes'' in it, i.e., bits that take
		 * up storage but don't participate in its value.
		 */
		while ( bits > 0 )
		{
			bits >>= 1;
			bit_count++;
		}

		return bit_count;
	}

	int float_bits()
	{
		switch ( FLT_RADIX )
		{
		case 2:
			return FLT_MANT_DIG;

		case 16:
			return FLT_MANT_DIG*4;

		default:
			return FLT_MANT_DIG*(log(FLT_RADIX)/log(2.0));
		}
	}

Note that these tests normally don't require any floating point arithmetic
(except the casts to "int" or "float").  The only floating point
arithmetic
would be if the floating point system is not binary or hexidecimal.

I haven't tested the above code so their might be ``off by one'' errors,
but you get the idea.

-FF
-------------------------------------------------------------------
(``I only use AOL for reading netnews.'')
Frank Farance, Farance Inc.
E-mail: frank@farance.com, Telephone: +1 212 486 4700
ISO JTC1/SC22/WG14 & ANSI X3J11 (C Programming Language) Project Editor
Technical Details
Message-ID: <40u7d4$20h@newsbf02.news.aol.com>
Path: arc1-ca.pugleaf.net!newsbf02.news.aol.com!not-for-mail
References: <40rjdn$jof@solutions.solon.com>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!newsbf02.news.aol.com!not-for-mail
From: ffarance@aol.com (FFarance)
Newsgroups: comp.std.c
Subject: Re: Casting float to int - standard bug?
Date: 16 Aug 1995 21:52:36 -0400
Organization: America Online, Inc. (1-800-827-6364)
Sender: root@newsbf02.news.aol.com
Message-ID: <40u7d4$20h@newsbf02.news.aol.com>
References: <40rjdn$jof@solutions.solon.com>
Reply-To: ffarance@aol.com (FFarance)
NNTP-Posting-Host: newsbf02.mail.aol.com