473,396 Members | 1,724 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Testing a float for equivalence to a double.

Hi,

I have some software that does the following (in an attempt to determine
whether the double x, can be represented just as accurately by a float):

void test_it(double x) {
float y = x;
if(x == y) {
printf("x can be represented precisely by a float\n");
}
else {
printf("x can't be represented precisely by a float\n");
}
}

Is this an acceptable way of determining whether the double can be
represented precisely by a float ? Is there some other (perhaps
preferable) way of doing it ?

One problem is that, with the above function, Microsoft compilers tell
you that x==y, no matter what the value of x. That strikes me as being
quite bizarre.

I'm wondering whether, to make the code portable, I should trick MS
compilers into doing what I think is right (which can be done fairly
simply) - or whether I should be concentrating on applying some other
method.

Thing is that I don't want to stuff around with getting that code to
work properly with MS compilers if the whole concept of that code is of
dubious merit to begin with.

Cheers,
Rob

--
To reply by email u have to take out the u in kalinaubears.

Nov 14 '05 #1
9 2380
On Wed, 16 Feb 2005 05:41:29 +0000, Sisyphus wrote:
Hi,

I have some software that does the following (in an attempt to determine
whether the double x, can be represented just as accurately by a float):

void test_it(double x) {
float y = x;
if(x == y) {
printf("x can be represented precisely by a float\n");
}
else {
printf("x can't be represented precisely by a float\n");
}
}

Is this an acceptable way of determining whether the double can be
represented precisely by a float ?
It is as far as standard C is concerned as long as fabs(x) <= FLOAT_MAX.
In the general case you should test for that as well.
Is there some other (perhaps preferable) way of doing it ?

One problem is that, with the above function, Microsoft compilers tell
you that x==y, no matter what the value of x. That strikes me as being
quite bizarre.
Compilers on some platforms, especially x86 ones often choose not to
follow the standard rules exactly because doing so entails a big
performance hit. They prefer to keep values in registers where possible so
they are held at higher precision than they should be.
I'm wondering whether, to make the code portable, I should trick MS
compilers into doing what I think is right (which can be done fairly
simply) - or whether I should be concentrating on applying some other
method.
This is a reasonable approach, and it isn't obvious what else you could
do without examining the representation which won't be portable. Because
we're in a situation where compilers are not following the standard there
is no competely portable method to do this. However making y volatile will
result in the correct behaviour on many compilers.
Thing is that I don't want to stuff around with getting that code to
work properly with MS compilers if the whole concept of that code is of
dubious merit to begin with.


The approach is sensible, it is just a case of making the compiler do the
right thing.

Lawrence
Nov 14 '05 #2

"Sisyphus" <ka**********@iinet.net.au> wrote in message
news:42***********************@per-qv1-newsreader-01.iinet.net.au...
Hi,

I have some software that does the following (in an attempt to determine
whether the double x, can be represented just as accurately by a float):

void test_it(double x) {
float y = x;
if(x == y) { .... One problem is that, with the above function, Microsoft compilers tell you
that x==y, no matter what the value of x. That strikes me as being quite
bizarre.


Perhaps both are compared as float values, so x is demoted to float and so
will always be the same as y? Or perhaps the parameter x is derived from a
float value elsewhere.

Bart
Nov 14 '05 #3

"Lawrence Kirby" <lk****@netactive.co.uk> wrote in message
news:pa****************************@netactive.co.u k...
On Wed, 16 Feb 2005 05:41:29 +0000, Sisyphus wrote:
Hi,

I have some software that does the following (in an attempt to determine
whether the double x, can be represented just as accurately by a float):

void test_it(double x) {
float y = x;
if(x == y) {
printf("x can be represented precisely by a float\n");
}
else {
printf("x can't be represented precisely by a float\n");
}
}

Is this an acceptable way of determining whether the double can be
represented precisely by a float ?
It is as far as standard C is concerned as long as fabs(x) <= FLOAT_MAX.
In the general case you should test for that as well.

Which cases would be affected by such an additional test? Does testing
representations of Infinity invoke UB? If so, does this fix it?
One problem is that, with the above function, Microsoft compilers tell
you that x==y, no matter what the value of x. That strikes me as being
quite bizarre.


Compilers on some platforms, especially x86 ones often choose not to
follow the standard rules exactly because doing so entails a big
performance hit. They prefer to keep values in registers where possible so
they are held at higher precision than they should be.
I'm wondering whether, to make the code portable, I should trick MS
compilers into doing what I think is right (which can be done fairly
simply) - or whether I should be concentrating on applying some other
method.

Do you consider setting SSE2 code generation as a "trick?" The approach is sensible, it is just a case of making the compiler do the
right thing.

Lawrence

Nov 14 '05 #4
Lawrence Kirby wrote:


This is a reasonable approach, and it isn't obvious what else you could
do without examining the representation which won't be portable. Because
we're in a situation where compilers are not following the standard there
is no competely portable method to do this. However making y volatile will
result in the correct behaviour on many compilers.


Thanks for the reply, Lawrence.

Didn't know about "volatile" - so I've just tried it out, but it doesn't
seem to be the answer in this case.

My solution (so far) is to write a separate function for MS compilers:

#ifdef _MSC_VER // identifies Microsoft compilers
void test_it(double x) {
float foo = x;
float y = foo;
if(x == y) {
printf("x can be represented precisely by a float\n");
}
else {
printf("x can't be represented precisely by a float\n");
}
}
#else // use the original

But that worked only if optimizations were not turned on - in which case
the only solution I could find was to turn 'em off:

#ifdef _MSC_VER
#pragma optimize("", off)
void test_it(double x) {
float foo = x;
float y = foo;
if(x == y) {
printf("x can be represented precisely by a float\n");
}
else {
printf("x can't be represented precisely by a float\n");
}
}
#pragma optimize("", on)
#else

But even that wouldn't work if -O1 optimization (minimize space) were
used - in which case an additional 'foo +=0;' was needed. So, a solution
which I *think* covers all cases with MS compilers is to have:

#ifdef _MSC_VER
#pragma optimize("", off)
void test_it(double x) {
float foo = x;
float y = foo;
foo += 0;
if(x == y) {
printf("x can be represented precisely by a float\n");
}
else {
printf("x can't be represented precisely by a float\n");
}
}
#pragma optimize("", on)
#else

I don't think I've added much overhead to the original (though I haven't
tested) but is there something I could try that is not quite so comical ?

Getting back to "volatile", I found that simply making y volatile did
not achieve the desired result - so I did:

volatile float foo = x;
volatile float y = foo;
if(x == y) { ...

But that still didn't do the right thing, so I added 'foo += 0;' as
before, but that produced something that Microsoft calls an "INTERNAL
COMPILER ERROR".

At that point I gave up on that approach :-)

Cheers,
Rob

--
To reply by email u have to take out the u in kalinaubears.

Nov 14 '05 #5
Sisyphus wrote:
Lawrence Kirby wrote:


This is a reasonable approach, and it isn't obvious what else you could
do without examining the representation which won't be portable. Because
we're in a situation where compilers are not following the standard there
is no competely portable method to do this. However making y volatile
will
result in the correct behaviour on many compilers.


Thanks for the reply, Lawrence.

Didn't know about "volatile" - so I've just tried it out, but it doesn't
seem to be the answer in this case.

My solution (so far) is to write a separate function for MS compilers:

#ifdef _MSC_VER // identifies Microsoft compilers
void test_it(double x) {
float foo = x;
float y = foo;
if(x == y) {
printf("x can be represented precisely by a float\n");
}
else {
printf("x can't be represented precisely by a float\n");
}
}
#else // use the original

But that worked only if optimizations were not turned on - in which case
the only solution I could find was to turn 'em off:

#ifdef _MSC_VER
#pragma optimize("", off)
void test_it(double x) {
float foo = x;
float y = foo;
if(x == y) {
printf("x can be represented precisely by a float\n");
}
else {
printf("x can't be represented precisely by a float\n");
}
}
#pragma optimize("", on)
#else

But even that wouldn't work if -O1 optimization (minimize space) were
used - in which case an additional 'foo +=0;' was needed. So, a solution
which I *think* covers all cases with MS compilers is to have:

#ifdef _MSC_VER
#pragma optimize("", off)
void test_it(double x) {
float foo = x;
float y = foo;
foo += 0;
if(x == y) {
printf("x can be represented precisely by a float\n");
}
else {
printf("x can't be represented precisely by a float\n");
}
}
#pragma optimize("", on)
#else

I don't think I've added much overhead to the original (though I haven't
tested) but is there something I could try that is not quite so comical ?

Getting back to "volatile", I found that simply making y volatile did
not achieve the desired result - so I did:

volatile float foo = x;
volatile float y = foo;
if(x == y) { ...

But that still didn't do the right thing, so I added 'foo += 0;' as
before, but that produced something that Microsoft calls an "INTERNAL
COMPILER ERROR".

At that point I gave up on that approach :-)


I usually use volatile indirectly:

void test_it(double x) {
float y = x;
if(*((volatile double *)&x) == *((volatile float *)&y)) {
printf("x can be represented precisely by a float\n");
}
else {
printf("x can't be represented precisely by a float\n");
}
}

Maybe this works for you, too. However, do not forget to check
against the maximum float value...
Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Nov 14 '05 #6
Michael Mair wrote:

I usually use volatile indirectly:

void test_it(double x) {
float y = x;
if(*((volatile double *)&x) == *((volatile float *)&y)) {
printf("x can be represented precisely by a float\n");
}
else {
printf("x can't be represented precisely by a float\n");
}
}
Thanks for the tip on usage, Michael - though it still doesn't coerce
the MS compiler into behaving as desired :-)

Maybe this works for you, too. However, do not forget to check
against the maximum float value...


Sorry - I should have mentioned that this function won't get called if
|x| is greater than the maximum float value. (ie such a condition will
be detected and dealt with before the function is called.)

Cheers,
Rob

--
To reply by email u have to take out the u in kalinaubears.

Nov 14 '05 #7
On Wed, 16 Feb 2005 14:11:14 +0000, Tim Prince wrote:

....
It is as far as standard C is concerned as long as fabs(x) <= FLOAT_MAX.
In the general case you should test for that as well.

Which cases would be affected by such an additional test? Does testing
representations of Infinity invoke UB? If so, does this fix it?


If you convert a value to float which is not within the range of
representable values of float you get undefined behaviour. Infinities are
not involved here.

Lawrence

Nov 14 '05 #8
Sisyphus wrote:
Michael Mair wrote:

I usually use volatile indirectly:

void test_it(double x) {
float y = x;
if(*((volatile double *)&x) == *((volatile float *)&y)) {
printf("x can be represented precisely by a float\n");
}
else {
printf("x can't be represented precisely by a float\n");
}
}
Thanks for the tip on usage, Michael - though it still doesn't coerce

the MS compiler into behaving as desired :-)

Cheers,
Rob


How about:

void test_it(double x) {
union{ float foo; float bar; } volatile schizo;
schizo.foo = x;
if(x == schizo.bar) {
printf("x can be represented precisely by a float\n");
}
else {
printf("x can't be represented precisely by a float\n");
}
}

I haven't tested it though.

Mark

Nov 14 '05 #9
Mark Piffer wrote:

How about:

void test_it(double x) {
union{ float foo; float bar; } volatile schizo;
schizo.foo = x;
if(x == schizo.bar) {
printf("x can be represented precisely by a float\n");
}
else {
printf("x can't be represented precisely by a float\n");
}
}


Not quite (nice try :-)

It works with optimization -O1, but fails with both -O2 and with no
optimizations.

Cheers,
Rob

--
To reply by email u have to take out the u in kalinaubears.

Nov 14 '05 #10

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

Similar topics

1
by: kingjames | last post by:
I have a c30 to ieee float converter algorithm that takes binary data from a c30, does some bit munipulation and stores the answer (i'm using unsigned longs for the processing). When I come up...
13
by: maadhuu | last post by:
hello , i would like to know as to why double is more efficient than float . thanking you, ranjan.
2
by: ozbear | last post by:
In C# is there a way to alias or equivalence one type to another? For example, in Delphi, I can say... type TMyFloat = type double; and then cheerfully use TMyFloat in my field definitions,...
5
by: Kubik | last post by:
Hi! Let's see, we got: float var=4.6f; //as we know 414/4.6 shoud be equal to 90 but Math.Ceiling(414/var) gives us 91 but (414/var).ToString() prints '90'.
6
by: karthi | last post by:
hi, I need user defined function that converts string to float in c. since the library function atof and strtod occupies large space in my processor memory I can't use it in my code. regards,...
60
by: Erick-> | last post by:
hi all... I've readed some lines about the difference between float and double data types... but, in the real world, which is the best? when should we use float or double?? thanks Erick
12
by: shaanxxx | last post by:
I wanted to write hash function float or double. Any suggestion would be appreciated.
23
by: JDT | last post by:
Hi, It seems that using floats as the first tupelo for an STL map (shown below) can cause problems but I don't remember what the problems were. Is it common practice to use a structure like...
3
by: Arnie | last post by:
Folks, We ran into a pretty significant performance penalty when casting floats. We've identified a code workaround that we wanted to pass along but also was wondering if others had experience...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.