473,808 Members | 2,882 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Compiler allowed to do this?

float nanometers(long pm)
{
return pm / 1000.0f;
}
void f()
{
if(nanometers(3 09311L) == nanometers(3093 11L))
{
// do something
}
}

The 'if' expression resolves to false, probably because one float value is stored and reloaded but
the other remains in the FPU in extended precision (I examined the assembler). I know you have to be
careful when comparing floats, but I'd expect the same values undergoing the same operations to end
up the _same_, and I'd like to know if the compiler is conforming to the standard.

The compiler is VS .NET 2003 in debug mode (no optimization) and with the /Op switch turned on
(improve float consistency).

DW
Sep 21 '06 #1
19 1772
David W wrote:
float nanometers(long pm)
{
return pm / 1000.0f;
}
void f()
{
if(nanometers(3 09311L) == nanometers(3093 11L))
{
// do something
}
}

The 'if' expression resolves to false, probably because one float value is
stored and reloaded but the other remains in the FPU in extended precision
(I examined the assembler). I know you have to be careful when comparing
floats, but I'd expect the same values undergoing the same operations to
end up the _same_, and I'd like to know if the compiler is conforming to
the standard.
[snip]

I think the compiler is within its rights. At least that is how I would
interpret the intention of [5/10]:

The values of the floating operands and the results of floating
expressions may be represented in greater precision and range than that
required by the type; the types are not changed thereby
Best

Kai-Uwe Bux
Sep 21 '06 #2
"Kai-Uwe Bux" <jk********@gmx .netwrote in message
news:ee******** **@murdoch.acc. Virginia.EDU...
David W wrote:
float nanometers(long pm)
{
return pm / 1000.0f;
}
void f()
{
if(nanometers(3 09311L) == nanometers(3093 11L))
{
// do something
}
}

The 'if' expression resolves to false, probably because one float value
is
stored and reloaded but the other remains in the FPU in extended
precision
(I examined the assembler). I know you have to be careful when comparing
floats, but I'd expect the same values undergoing the same operations to
end up the _same_, and I'd like to know if the compiler is conforming to
the standard.
[snip]

I think the compiler is within its rights. At least that is how I would
interpret the intention of [5/10]:

The values of the floating operands and the results of floating
expressions may be represented in greater precision and range than that
required by the type; the types are not changed thereby
Well, that's just asking for bugs, IMO. Intuitively, most programmers would
expect the 'if' expression to be true, even those who are aware of round-off
issues with floats. The original code from which I created the example
worked on an earlier compiler, but now it doesn't and I can't even force the
compiler to make it work. It is a large project and I don't know where else
there will be similar bugs, and it won't be easy to find out. Either the
standard or the compiler should be better than this. It is reasonable that
identical expressions with identical inputs should produce identical
results. It should not be necessary to complicate the code with some
arbitrary maximum epsilon in a case like this.

DW

Sep 21 '06 #3
David W wrote:
>I think the compiler is within its rights. At least that is how I would
interpret the intention of [5/10]:

The values of the floating operands and the results of floating
expressions may be represented in greater precision and range than that
required by the type; the types are not changed thereby

Well, that's just asking for bugs, IMO. Intuitively, most programmers
would expect the 'if' expression to be true, even those who are aware of
round-off issues with floats. The original code from which I created the
example worked on an earlier compiler, but now it doesn't and I can't even
force the compiler to make it work.
What you need is a directive to prevent that the compiler holds the values
in registers, where they have another precision as if hold in memory. I do
not know, if this is a general solution (I'm using gcc), but I declare such
variables that should not be hold in registers as volatile, which tells the
compiler that the value can change unexpected from external events not
under his control. This prevents certain optimization, especially holding
the value in a register.

Regards
Stephan
Sep 21 '06 #4

"Stephan Kuhagen" <no****@domain. tldwrote in message
news:ee******** **@kohl.informa tik.uni-bremen.de...
David W wrote:
>>I think the compiler is within its rights. At least that is how I would
interpret the intention of [5/10]:

The values of the floating operands and the results of floating
expressions may be represented in greater precision and range than
that
required by the type; the types are not changed thereby

Well, that's just asking for bugs, IMO. Intuitively, most programmers
would expect the 'if' expression to be true, even those who are aware of
round-off issues with floats. The original code from which I created the
example worked on an earlier compiler, but now it doesn't and I can't
even
force the compiler to make it work.

What you need is a directive to prevent that the compiler holds the values
in registers, where they have another precision as if hold in memory. I do
not know, if this is a general solution (I'm using gcc), but I declare
such
variables that should not be hold in registers as volatile, which tells
the
compiler that the value can change unexpected from external events not
under his control. This prevents certain optimization, especially holding
the value in a register.
How about just assigning the results to variables, and later comparing those
variables? Then the values should be equal. (Right?)

-Howard

Sep 21 '06 #5
"Stephan Kuhagen" <no****@domain. tldwrote in message
news:ee******** **@kohl.informa tik.uni-bremen.de...
David W wrote:
Well, that's just asking for bugs, IMO. Intuitively, most programmers
would expect the 'if' expression to be true, even those who are aware of
round-off issues with floats. The original code from which I created the
example worked on an earlier compiler, but now it doesn't and I can't
even
force the compiler to make it work.

What you need is a directive to prevent that the compiler holds the values
in registers, where they have another precision as if hold in memory. I do
not know, if this is a general solution (I'm using gcc), but I declare
such
variables that should not be hold in registers as volatile, which tells
the
compiler that the value can change unexpected from external events not
under his control. This prevents certain optimization, especially holding
the value in a register.
Yes, the compiler should certainly offer this, but I suspect that it
doesn't. It seems wrong to me that I'm not getting what I asked for. The
function return type is specified is float, not double, but I'm getting a
float for one call and a double for the other. If the compiler did what I
asked and produced a float in both cases, at least when an equality is used,
there wouldn't be a problem. This is the worst kind of inconsistency and is
taking the latitude the standard allows too far.

DW

Sep 21 '06 #6
"Howard" <al*****@hotmai l.comwrote in message
news:0c******** ***********@bgt nsc05-news.ops.worldn et.att.net...
>
How about just assigning the results to variables, and later comparing
those
variables? Then the values should be equal. (Right?)
Right, but that doesn't solve my problem of how to determine where else this
bug is occurring in a large project that used to not have it.

DW

Sep 21 '06 #7

"David W" <no@email.provi dedwrote in message
news:45******@n ews.eftel.com.. .
"Howard" <al*****@hotmai l.comwrote in message
news:0c******** ***********@bgt nsc05-news.ops.worldn et.att.net...
>>
How about just assigning the results to variables, and later comparing
those
>variables? Then the values should be equal. (Right?)

Right, but that doesn't solve my problem of how to determine where else
this
bug is occurring in a large project that used to not have it.
Well, the project did have a problem already, and that was that it was
relying on behavior which is not guaranteed.

As for where else you have this problem, there's no way anyone here can tell
you. You'll just have to look at your own code, large or not. I don't know
of any way around it, sorry.

But it seems odd to me that you're comparing the results of two identical
function calls in the first place. I'm guessing this was just a made-up
test to try to replicate a real-life situation you have? If that's the
case, then you probably shouldn't be relying on two real values comparing as
exactly equal in the first place.

If you got those values from the exact same code (as in your example), then
you already know they're equal, and shouldn't need to compare. If you
obtained two values from different methods, but whose values (on paper)
should compare as equal, then you just need to know that they may not always
compare as equal.

It's often better to avoid comparisons of real numbers for exact equality,
except in specific cases, such as where they both hold integral values of
small enough magnitude. Instead, select an error value that's sufficiently
small for your purposes, and compare for equality within plus or minus that
error value. (Or, you might be able to use some other method for making
decisions which doesn't rely on the values at all.)

-Howard
Sep 21 '06 #8
"Howard" <al*****@hotmai l.comwrote in message
news:i2******** ***********@bgt nsc05-news.ops.worldn et.att.net...
>
"David W" <no@email.provi dedwrote in message
news:45******@n ews.eftel.com.. .
"Howard" <al*****@hotmai l.comwrote in message
news:0c******** ***********@bgt nsc05-news.ops.worldn et.att.net...
>
How about just assigning the results to variables, and later comparing
those
variables? Then the values should be equal. (Right?)
Right, but that doesn't solve my problem of how to determine where else
this
bug is occurring in a large project that used to not have it.

Well, the project did have a problem already, and that was that it was
relying on behavior which is not guaranteed.
Yes, but it's an understandable problem. I don't imagine there are many programmers who would
instinctively think it's a risky thing to do. In how many programming languages would this not work?
As for where else you have this problem, there's no way anyone here can tell
you. You'll just have to look at your own code, large or not. I don't know
of any way around it, sorry.
I wasn't asking for help on that. I was only pointing out the trouble that this unreasonable
compiler behaviour has caused.
But it seems odd to me that you're comparing the results of two identical
function calls in the first place. I'm guessing this was just a made-up
test to try to replicate a real-life situation you have?
Of course.
If that's the
case, then you probably shouldn't be relying on two real values comparing as
exactly equal in the first place.
Why? I have the same starting values - two identical longs - and they are undergoing exactly the
same operations. Naturally they should be produce the same result, even in floats.
If you got those values from the exact same code (as in your example), then
you already know they're equal, and shouldn't need to compare.
I don't know they are equal in the real program, where the longs are variables, not compile-time
constants.
If you
obtained two values from different methods, but whose values (on paper)
should compare as equal, then you just need to know that they may not always
compare as equal.

It's often better to avoid comparisons of real numbers for exact equality,
except in specific cases, such as where they both hold integral values of
small enough magnitude.
Or if you have identical starting values and you do identical things to them.
Instead, select an error value that's sufficiently
small for your purposes, and compare for equality within plus or minus that
error value.
Shouldn't have to do that in this case. The float values of the two results are the _same_. The
problem is that the compiler is not comparing a float with a float, even though that's what the code
says to do.

DW
Sep 21 '06 #9
David W wrote:
>
Yes, the compiler should certainly offer this, but I suspect that it
doesn't. It seems wrong to me that I'm not getting what I asked for. The
function return type is specified is float, not double, but I'm getting a
float for one call and a double for the other. If the compiler did what I
asked and produced a float in both cases, at least when an equality is used,
there wouldn't be a problem. This is the worst kind of inconsistency and is
taking the latitude the standard allows too far.
OT, since it's compiler specific, but look at the /fp option.
Sep 22 '06 #10

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

Similar topics

13
1872
by: Neil Zanella | last post by:
Hello, I wonder whether anyone has ever come across the following g++ compiler error message. I don't recall ever seeing it before. I solved my problem but I am still not sure about what this message is all about. Any ideas? error: invalid initialization of non-const reference of
8
1832
by: grundmann | last post by:
Hello, i got a strange compiler error. When compiling the following: // forward declarations typedef AvlTree<LineSegment,LineSegmentComperator> LSTree; void handleEventPoint (const EventPoint& , LSTree& , double&, std::list<IntersectionPoint>& );
6
1659
by: cody | last post by:
public decimal Wert { get{return this.wert;} set{this.wert=value;} } This doesn't compile. It gives me error CS0592 and says that obsolete cannot be applied to that elemet.
5
1950
by: Ondrej Spanel | last post by:
I though that inline functions should be always visible only in the compilation unit where they are defined - meaning if compiler cannot inline them, they should be handled as if declared static. However sample attached shows VC compiler does not work this way (tested in .NET 2003). When you compile the sample with inlining enabled (like in default Release config), the output is A1 = 1, A2 = 2. When run with inlining disabled (Debug),...
3
2857
by: trond.norbye | last post by:
Hi I am trying to compile a quite large software system with a new compiler. During that attempt I am facing problems during the link phase, and I have traced it down to the following construct: test.cc: class Foo { public:
8
5319
by: Jess | last post by:
Hi, I have a template function that triggered some compiler error. The abridged version of the class and function is: #include<memory> using namespace std; template <class T>
43
3845
by: JohnQ | last post by:
Are a default constructor, destructor, copy constructor and assignment operator generated by the compiler for a struct if they are not explicitely defined? I think the answer is yes, because "there is no difference between a struct and a class except the public/private access specification" (and a few minor other things). When I create a class, I always start by declaring the default constructor, copy constructor and assignment operator...
2
2211
by: talkaboutquality | last post by:
Need to define a macro as, say, #ifdef NEED_FUNCTION foo(x) #else #endif
7
1509
by: spasmous | last post by:
If a compiler see's the following statement c = (a+b)-b will it optimize it to c=a? I want to force the compiler to evaluate (a +b) first. Do the parentheses ensure an ANSI conforming compiler HAS to do that? If not, is there a way?
35
2916
by: =?Utf-8?B?UElFQkFMRA==?= | last post by:
I'd really like to be able to constrain a generic type to System.Enum or, better, enum. But of course that results in "Compiler Error CS0702". So far I've been checking the type parameter at runtime and throwing an exception if the provided type is not an enum. That works, but it just doesn't seem quite right. After reading through section 4.4.4 of the C# 3.0 spec I see no reason why constraining to System.Enum should not be allowed.
0
9721
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10631
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10374
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10374
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10114
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9196
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6880
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
1
4331
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
3011
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.