Can cout alter variables somehow? - c++

So I have a function that looks something like this:
float function(){
float x = SomeValue;
return x / SomeOtherValue;
}
At some point, this function overflows and returns a really large negative value. To try and track down exactly where this was happening, I added a cout statement so that the function looked like this:
float function(){
float x = SomeValue;
cout << x;
return x / SomeOtherValue;
}
and it worked! Of course, I solved the problem altogether by using a double. But I'm curious as to why the function worked properly when I couted it. Is this typical, or could there be a bug somewhere else that I'm missing?
(If it's any help, the value stored in the float is just an integer value, and not a particularly big one. I just put it in a float to avoid casting.)

Welcome to the wonderful world of floating point. The answer you get will likely depend on the floating point model you compiled the code with.
This happens because of the difference between the IEEE spec and the hardware the code is running on. Your CPU likely has 80 bit floating point registers that get use to hold the 32-bit float value. This means that there is far more precision while the value stays in a register than when it is forced to a memory address (also known as 'homing' the register).
When you passed the value to cout the compiler had to write the floating point to memory, and this results in a lost of precision and interesting behaviour WRT overflow cases.
See the MSDN documentation on VC++ floating point switches. You could try compiling with /fp:strict and seeing what happens.

Printing a value to cout should not change the value of the paramter in any way at all.
However, I have seen similar behaviour, adding debugging statements causes a change in the value. In those cases, and probably this one as well my guess was that the additional statements were causing the compiler's optimizer to behave differently, so generate different code for your function.
Adding the cout statement means that the vaue of x is used directly. Without it the optimizer could remove the variable, so changing the order of the calculation and therefore changing the answer.

As an aside, it's always a good idea to declare immutable variables using const:
float function(){
const float x = SomeValue;
cout << x;
return x / SomeOtherValue;
}
Among other things this will prevent you from unintentionally passing your variables to functions that may modify them via non-const references.

cout causes a reference to the variable, which often will cause the compiler to force it to spill it to the stack.
Because it is a float, this likely causes its value to be truncated from the double or long double representation it would normally have.
Calling any function (non-inlined) that takes a pointer or reference to x should end up causing the same behavior, but if the compiler later gets smarter and learns to inline it, you'll be equally screwed :)

I dont think the cout has any effect on the variable, the problem would have to be somewhere else.

Related

Is the a difference between returning a value and saving it to a variable and returning that variable?

I was working on college stuff and I wondered of the difference between this:
double TComplejo::Mod(void) const
{
double a = sqrt(re * re + im * im);
return a;
}
and this:
double TComplejo::Mod(void) const
{
return sqrt(re * re + im * im);
}
Both re and im are doubles.
I was warned that "Second code snippet could reside in a decimal precision issue".
There is no real difference between the 2 code snippets:
The precision aspect:
Both snippets deal only with doubles (with no conversion).
Storing the double expression in a variable and then returning it is identical sematically to returning it directly.
The performance aspect:
Due copy-elision (RVO) the generated asembly code is likely to be the same with modern compilers. Even before C++17 with mandatory copy elision, most compilers would produce the same code for the 2 snippets.
For example: as you can see here (Godbolt) GCC (with -O2) produces the same code for both snippets.
This post discussing What exactly is the "as-if" rule? contains some more relevant info that should make it clear why the 2 snippets should behave the same.
From a pure semantic point of view, the two codes have absolutely the same effect. The modulus is computed as a double-precision number. Whether it is temporarily stored in a double variable or not makes no difference. By the way, the optimizing compiler will most probably implement the first version like the second, recognizing that the temporary storage is useless.
Anyway, from a pragmatic point of view a difference could exist on the x86/x64 platform where the FPU registers are 80 bits rather than 64. In some optimization modes, the data is kept in those registers rather than copied back to memory with rounding. So the 80 bits computed value could be used straight from the FPU register for the next computations.
Anyway, it is unlikely that in this circumstance, using a temporary will force rounding to 64 bits. In any case, the second form could only be more accurate.

Adding double precision values yield different results between separate programs in C++

I have a question about floating point addition. I understand how compilers and processor architecture can lead to floating point arithmetic values. I have seen many questions on here similar to my question, but they all have some variation such as different compiler, different code, different machine, etc. However, I'm am running into an issue when adding doubles in the exact same way in two different programs calling the identical function with the same arguments and it is leading to different results. Both programs are compiled on the same machine with the same compiler/tags. The code looks similar to this:
void function(double tx, double ty, double tz){
double answer;
double x,y;
x = y = answer = 0;
x = tx - ty;
y = ty - tz;
answer = (tx + ty + tz) * (x*y)
}
The values of:
tx,ty,tz
are on the order of [10e-15,10e-30]. Obviously this is a very simplified version of the functions I am actually using, but, is it possible for two programs, running identical floating point arithmetic (not just the same function, the exact same code), on the same machine, with the same compiler/tags, to get different results for the function?
Some possibilities:
The source code of function is identical in the two programs, but it appears with different context, resulting in the compiler compiling it in different ways. For example, the compiler might inline it in one place and not another, and inlining might lead to some expression reduction due to combination with other expressions at the point of the inlined call, and hence different arithmetic is performed. (To test this, move function to a separate source file, compile it separately, and link it with a linker without cross-module optimization. Also, try compiling with optimization disabled.)
You think there are identical inputs to function because they appear the same when printed or viewed in the debugger, but they are actually different due to small differences in the low digits that are not printed. (To test this, print the full values using the hexadecimal floating-point format. To do that, insert std::hexfloat into the output stream, followed by floating-point values. Alternately, use a C printf using the %a format.)
Something else in the programs changes floating-point state, such as rounding mode.
You think you have used an identical compiler, identical sources, identical compilation switches, and so on, but actually have not.
David Schwartz notes that floating-point values can change when they are stored, as occurs when they are simply spilled to the stack. This occurs because some processors and C++ implementations may store floating-point values with extended precision in registers but less precision in memory. Technically, this fits into either 1. (different computation nominally inside function) or 2. (different values passed to function), but it is insidious enough to warrant separate mention.
Well the answer is quite easy. If your computer behaves deterministic it will always return the same results for the same input. That's the basic idea behind programming languages so far. (Unless we are talking about quantum computers, of course.)
So the question reduces to whether you really have the same input.
Although the above function looks strictly functional, there are often hidden inputs that are not that obvious. E.g. you might adjust the rounding mode of your FPU before calling the function. Or you might setup different exception behavior. In both cases the function may behave differently for certain inputs.
So even if your computer isn't non-deterministic (i.e. buggy) the above function might return different results. Although it is not that likely.

Taking a root higher than 2

I'm trying to take the 11th root of an expression and I'm getting a return of -inf.
std::cout << pow(j,(1.0/11.0)) << std::endl;
where j is just some log expression. I've checked that number to make sure it's valid, and it is. I'm thinking it's the way that the power expression is being run. Is there a better way to do this? Thanks.
And yes, I've included cmath into my work.
I can't think of a valid reason for pow to return -inf, if your inputs are marginally sane. However in case you're passing in a negative number, something that may be worth trying is:
if(j==0) return 0;
if(j<0) return -pow(-j, 1.0/11.0);
return pow(j,1.0/11.0);
try to look for FPU errors
the most common is forgotten return of float/double in some function
which leads to problems on FPU stack which is really small.
also you can try add this before pow
asm { fninit; };
this resets the FPU so if you have problems on stack it will help
but of course do not do this in middle of some FPU computation
it would destroy its result
if you are not on x87 platform than this will not help
the value of j before crash will be a good start to share with us.
try to store the result of pow to some float/double variable
cout that variable not temporary heap memory location
if it prints -inf look also inside that variable if it is also -inf
(could be something wrong with the cout not pow ... )
minimize your code (turn off everything part by part)
and see if the problems is suddenly not there
hidden memory leaks and code overwrites are evil ...
Let us know what you have found.

strange results with /fp:fast

We have some code that looks like this:
inline int calc_something(double x) {
if (x > 0.0) {
// do something
return 1;
} else {
// do something else
return 0;
}
}
Unfortunately, when using the flag /fp:fast, we get calc_something(0)==1 so we are clearly taking the wrong code path. This only happens when we use the method at multiple points in our code with different parameters, so I think there is some fishy optimization going on here from the compiler (Microsoft Visual Studio 2008, SP1).
Also, the above problem goes away when we change the interface to
inline int calc_something(const double& x) {
But I have no idea why this fixes the strange behaviour. Can anyone explane this behaviour? If I cannot understand what's going on we will have to remove the /fp:fastswitch, but this would make our application quite a bit slower.
I'm not familiar enough with FPUs to comment with any certainty, but my guess would be that the compiler is letting an existing value that it thinks should be equal to x sit in on that comparison. Maybe you go y = x + 20.; y = y - 20; y is already on the FP stack, so rather than load x the compiler just compares against y. But due to rounding errors, y isn't quite 0.0 like it is supposed to be, and you get the odd results you see.
For a better explanation: Why is cos(x) != cos(y) even though x == y? from the C++FAQ lite. This is part of what I'm trying to get across, I just couldn't remember where exactly I had read it until just now.
Changing to a const reference fixes this because the compiler is worried about aliasing. It forces a load from x because it can't assume its value hasn't changed at some point after creating y, and since x is actually exactly 0.0 [which is representable in every floating point format I'm familiar with] the rounding errors vanish.
I'm pretty sure MS provides a pragma that allows you to set the FP flags on a per-function basis. Or you could move this routine to a separate file and give that file custom flags. Either way, it could prevent your whole program from suffering just to keep that one routine happy.
what are the results of calc_something(0L), or calc_something(0.0f) ? It could be linked to the size of the types before casting. An integer is 4 bytes, a double is 8.
Have you tried looking at the asembled code, to see how the aforementioned conversion is done ?
Googling for 'fp fast', I found this post [social.msdn.microsoft.com]
As I've said in other question, compilers suck at generating floating point code. The article Dennis links to explains the problems well. Here's another: An MSDN article.
If the performance of the code is important, you can easily1 out-perform the compiler by writing your own assembler code. If your algoritm is vectorisable then you can make use of SIMD too (with a slight loss of precision though).
Assuming you understand the way the FPU works.
inline int calc_something(double x) will (probably) use an 80 bits register. inline int calc_something(const double& x) would store the double in memory, where it takes 64 bits. That at least explains the difference between the two.
However, I find your test quite fishy to begin with. The results of calc_something are extremely sensitive to rounding of its input. Your FP algorithms should be robust to rounding. calc_something(1.0-(1.0/3.0)*3) should be the same as calc_something(0.0).
I think the behavior is correct.
You never compare a floating point number up to less than the holding type's precision.
Something that comes from zero may be equal, greater or less than another zero.
See http://floating-point-gui.de/

Implicit casting Integer calculation to float in C++

Is there any compiler that has a directive or a parameter to cast integer calculation to float implicitly. For example:
float f = (1/3)*5;
cout << f;
the "f" is "0", because calculation's constants(1, 3, 10) are integer. I want to convert integer calculation with a compiler directive or parameter. I mean, I won't use explicit casting or ".f" prefix like that:
float f = ((float)1/3)*5;
or
float f = (1.0f/3.0f)*5.0f;
Do you know any c/c++ compiler which has any parameter to do this process without explicit casting or ".f" thing?
Any compiler that did what you want would no longer be a conforming C++ compiler. The semantics of integer division are well specified (at least for positive numbers), and you're proposing to change that.
It would also be dangerous since it would wind up applying to everything, and you might at some point have code that relies on standard integer arithmetic, which would silently be invalid. (After all, if you had tests that would catch that, you presumably would have tests that would catch the undesired integer arithmetic.)
So, the only advice I've got is to write unit tests, have code reviews, and try to avoid magic numbers (instead defining them as const float).
If you don't like either of the two methods you mentioned, you're probably out of luck.
What are you hoping to accomplish with this? Any specialized operator that did "float-division" would have to convert ints to floats at some point after tokenization, which means you're not going to get any performance benefit on the execution.
In C++ it's a bit odd to see a bunch of numeric values sprinkled through the code. Generally it is considered best practice to move any 'magic numbers' like these to their own static const float value, which removes this problem.
No, those two options are the best you have.