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 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
"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
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
"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
"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
"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
"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
"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
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. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
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
|
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>& );
|
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.
|
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),...
|
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:
| |
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>
|
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...
|
by: talkaboutquality |
last post by:
Need to define a macro as, say,
#ifdef NEED_FUNCTION
foo(x)
#else
#endif
|
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?
|
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.
|
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...
| |
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...
|
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...
|
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,...
|
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...
|
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...
|
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();...
| |
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
|
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...
| |