472,955 Members | 2,215 Online

# Finding next largest/smallest floating point value

I have a floating point number. I'd like to get the nearest floating
point number that is larger or smaller than the given number. I
investigated FLT_EPSILON but it only seems to be useful if the given
number is 1. Any suggestions?

Thanks,
-Peter
Nov 14 '05 #1
13 5058
Peter Ammon wrote:
I have a floating point number. I'd like to get the nearest floating
point number that is larger or smaller than the given number. I
investigated FLT_EPSILON but it only seems to be useful if the given
number is 1. Any suggestions?

You have to scale epsilon to find the number that results when
you change the least significant bit for any given floating point
number. This is quite complicated IIRC, especially when the
exponent changes.

The following link might cover it. I don't know, haven't read it
yet, but it seems to be very good so I am including it even if#
it is not relevant to your question.

http://docs.sun.com/source/806-3568/ncg_goldberg.html

--
Thomas.

Nov 14 '05 #2
I'm sure there's a better way, but:

float num, nextnum,guess;

// can't just add 1.0, because 1.0 could be less than a sig. bit
// play with + or -

guess = num+num;
do {
nextnum = guess;
guess = (num + nextnum) / 2.0;
}
while ((guess != num) && (guess != nextnum)); // could round down or up
"Peter Ammon" <pe*********@rocketmail.com> wrote in message
news:ca**********@news.apple.com...
I have a floating point number. I'd like to get the nearest floating
point number that is larger or smaller than the given number. I
investigated FLT_EPSILON but it only seems to be useful if the given
number is 1. Any suggestions?

Thanks,
-Peter

Nov 14 '05 #3
Peter Ammon wrote:

I have a floating point number. I'd like to get the nearest
floating point number that is larger or smaller than the given
number. I investigated FLT_EPSILON but it only seems to be
useful if the given number is 1. Any suggestions?

#include <float.h>

float scaledepsilon(float number)
{
float trial;

trial = number * FLT_EPSILON;
while (number != (number - trial/2.0) trial = number/2.0;
return trial;
} /* untested, but should be close */

Probably highly suspicious for very small values of number.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #4

Peter Ammon wrote:
I have a floating point number. I'd like to get the nearest floating
point number that is larger or smaller than the given number. I
investigated FLT_EPSILON but it only seems to be useful if the given
number is 1. Any suggestions?

Thanks,
-Peter

If you have a C99 compiler you can use the nextafter functions in math.h

7.12.11.3 The nextafter functions

double nextafter(double x, double y);
float nextafterf(float x, float y);
long double nextafterl(long double x, long double y);

Description
The nextafter functions determine the next representable value, in the
type of the function, after x in the direction of y, where x and y are
first converted to the type of the function. The nextafter functions
return y if x equals y. A range error may occur if the magnitude of x is
the largest finite value representable in the type and the result is
infinite or not representable in the type.

Returns
The nextafter functions return the next representable value in the
specified format after x in the direction of y.

Nov 14 '05 #5
In <Gu*********************@twister.southeast.rr.co m> Arin Chaudhuri <ar*****************@yahoo.com> writes:
Peter Ammon wrote:
I have a floating point number. I'd like to get the nearest floating
point number that is larger or smaller than the given number. I
investigated FLT_EPSILON but it only seems to be useful if the given
number is 1. Any suggestions?

If you have a C99 compiler you can use the nextafter functions in math.h

Nope, you need an implementation of the C99 standard library for that,
not a C99 compiler.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #6
Dan Pop wrote:
Nope, you need an implementation of the C99 standard library for that,
not a C99 compiler.

Dan

Thanks for correcting me.

Nov 14 '05 #7
Peter Ammon wrote:
I have a floating point number. I'd like to get the nearest floating
point number that is larger or smaller than the given number. I
investigated FLT_EPSILON but it only seems to be useful if the given
number is 1. Any suggestions?

Thanks,
-Peter

FLT_EPSILON is the smallest value, when added to 1.0 results in a
value greater than 1.0. If you multiply a float value by 1.0 +
FLT_EPSILON I suppose you'll get its next larger value.

--
Joe Wright mailto:jo********@comcast.net
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Nov 14 '05 #8

Joe Wright wrote:
FLT_EPSILON is the smallest value, when added to 1.0 results in a value
greater than 1.0. If you multiply a float value by 1.0 + FLT_EPSILON I
suppose you'll get its next larger value.

I guess the next representable number after x will be
x+FLT_EPSILON, if 1<=x<2,
x+2FLT_EPSILON if 2<=x<4
x+4FLT_EPSILON if 4<=x<8
etc.

The following program does not contradict my conjecture.

#include <stdio.h>
#include <math.h>
#include <float.h>

int
main(void)
{
float x=1.5f,y=100.0f;
if ( (x*(1.f+FLT_EPSILON)) == nextafterf(x,y))
{
printf("equal1\n");
}
else if( x+FLT_EPSILON == nextafterf(x,y) )
{
printf("equal2\n");
}
x=2.f;
if ( x+FLT_EPSILON == nextafterf(x,y))/*x
{
printf("equal1\n");
}
else if( x+(FLT_EPSILON+FLT_EPSILON) == nextafterf(x,y) )
{
printf("equal2\n");
}
return 0;
}

Nov 14 '05 #9

Arin Chaudhuri wrote:
I guess the next representable number after x will be
x+FLT_EPSILON, if 1<=x<2,
x+2FLT_EPSILON if 2<=x<4
x+4FLT_EPSILON if 4<=x<8
etc.

I am assuming FLT_RADIX=2, in general I guess the powers of two should
be replaced by the powers of

Nov 14 '05 #10
Arin Chaudhuri wrote:

Arin Chaudhuri wrote:
I guess the next representable number after x will be
x+FLT_EPSILON, if 1<=x<2,
x+2FLT_EPSILON if 2<=x<4
x+4FLT_EPSILON if 4<=x<8
etc.

I am assuming FLT_RADIX=2, in general I guess the powers of two should
be replaced by the powers of

And we're talking about C. Do you have anything that compiles in C?
--
Joe Wright mailto:jo********@comcast.net
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Nov 14 '05 #11
Arin Chaudhuri wrote:

Joe Wright wrote:
FLT_EPSILON is the smallest value, when added to 1.0 results in a
value greater than 1.0. If you multiply a float value by 1.0 +
FLT_EPSILON I suppose you'll get its next larger value.

I guess the next representable number after x will be
x+FLT_EPSILON, if 1<=x<2,
x+2FLT_EPSILON if 2<=x<4
x+4FLT_EPSILON if 4<=x<8
etc.

The following program does not contradict my conjecture.

#include <stdio.h>
#include <math.h>
#include <float.h>

int
main(void)
{
float x=1.5f,y=100.0f;
if ( (x*(1.f+FLT_EPSILON)) == nextafterf(x,y))
{
printf("equal1\n");
}
else if( x+FLT_EPSILON == nextafterf(x,y) )
{
printf("equal2\n");
}
x=2.f;
if ( x+FLT_EPSILON == nextafterf(x,y))/*x
{
printf("equal1\n");
}
else if( x+(FLT_EPSILON+FLT_EPSILON) == nextafterf(x,y) )
{
printf("equal2\n");
}
return 0;
}

What is nextafterf()? I do see it declared in my math.h in a
non-posix and non-ansi context (djgpp gcc 3.0) but it doesn't seem
to be in my info system.

After removing the /*x you left around, the code did compile but
with the -Wall -ansi switches we see nextafterf not explicitly
declared and the program not 'working'.
--
Joe Wright mailto:jo********@comcast.net
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Nov 14 '05 #12

Joe Wright wrote:
Arin Chaudhuri wrote: Joe Wright wrote: What is nextafterf()? I do see it declared in my math.h in a non-posix
and non-ansi context (djgpp gcc 3.0) but it doesn't seem to be in my
info system.

After removing the /*x you left around, the code did compile but with
the -Wall -ansi switches we see nextafterf not explicitly declared and
the program not 'working'.

I apologize for the trouble caused by the /*.
nextafterf is a part of the C99 standard library, please have a look at
section 7.12.11.3 of the standard. The prototype of nextafterf should be
defined in math.h, I have copypasted the relevant portion of the
standard at the end of the post.

I reasoned as follows (assuming the radix to be 2) :

If, b = b0.b1 b2 b3 ... bp x 2^{e}

is a positive normalized float value, (b0=1)
then the next normalized value that can be represented can be obtained
0. 0 0 0 ... 1 x 2^{e}= 1. 0 0 0 ... 2^{e-p} = 2^eFLT_EPSILON
to the above, i.e, we increment the last possible "digit".

Hence, for float values of the form, f x 2^{e} with 1<=f<2 the next
normalized number that can be represented is obtained by adding 2^e
FLT_EPSILON

This will not work when we enter the zone of denormalized numbers, (when
b0 is 0 and e is the smallest value possible).

****
7.12.11.3 The nextafter functions

Synopsis
1 #include <math.h>
double nextafter(double x, double y);
float nextafterf(float x, float y);
long double nextafterl(long double x, long double y);

Description
The nextafter functions determine the next representable value, in the
type of the function, after x in the direction of y, where x and y are
first converted to the type of the function. The nextafter functions
return y if x equals y. A range error may occur if the magnitude of x is
the largest finite value representable in the type and the result is
infinite or not representable in the type.

Returns
The nextafter functions return the next representable value in the
specified format after x in the direction of y.

Nov 14 '05 #13

Arin Chaudhuri wrote:

This will not work when we enter the zone of denormalized numbers, (when
b0 is 0 and e is the smallest value possible).

What I meant here was e takes the value FLT_MIN_EXP, and please correct
me if I am wrong, there might exist implementations which do not have
denormals.

Nov 14 '05 #14

This thread has been closed and replies have been disabled. Please start a new discussion.