Type casting/ conversion dilemma - c++

I'm still only starting out in C++ and haven't dealt with much type casting yet. I was under the impression that the syntax is (type) (variables) however, this does not seem to work in this case.
float calcSphere (int radius)
{
float sphereSA;
sphereSA = (4 * PI * (radius*radius));
return sphereSA;
}
PI is a symbolic constant declared using #define PI 3.14 at the top of the code, I attempted to fix this problem by using (float) (4 * PI * (radius*radius)) but this did not solve anything. Google seems to return pretty obscure results on the subject too. Any solutions?

Just a guess but, are you getting a warning about initialization casting a double to a float (using MSVS)? Or possibly it's messing up b/c everything is ending up being cast as an integer b/c of the '4'?
If so, the problem is that when you type out a number it's a double. But you're using it as a float, to resolve it, that number needs to be what is cast. E.g.
sphereSA = ((float) 4 * (float) PI * radius * radius);
But, it would be better to give the compiler some type information about PI. E.g.
namespace MyConstants {
const float PI = 3.141;
}
sphereSA = ((float) 4 * MyConstants::PI * radius * radius);

You're using the C style cast. The syntax for casts has changed with C++.
You want to look for something like this:
dynamic_cast<something*>( yourthing );

Related

Converting float to long pointer and back to float pointer [duplicate]

This question already has answers here:
John Carmack's Unusual Fast Inverse Square Root (Quake III)
(6 answers)
Closed 4 years ago.
I am trying to understand the below code snippet taken from here
float Q_rsqrt( float number )
{
long i;
float x2, y;
const float threehalfs = 1.5F;
x2 = number * 0.5F;
y = number;
i = * ( long * ) &y; // evil floating point bit level hacking
i = 0x5f3759df - ( i >> 1 ); // ???
y = * ( float * ) &i;
y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration
// y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed
return y;
}
What I dont understand is the conversion from float to long pointer and back to float pointer. Why cant we simply do i=y instead of first referencing and then dereferencering the float.
I am new to pointer conversions, so please bear with me.
This code snipped is obviously the fast inverse square root. The pointer semantics there are not really used to do pointer things, but to reinterpret the bits at a certain memory location as a different type.
If you were to assign i=y this would be turned into a truncating conversion from floating point to integer. This however is not what's desired here. What you actually want is raw access to the bits, which is not straightforward possible on a floating point typed variable.
Let's break this statement down:
i = * ( long * ) &y;
&y: address of y. The type of this expression is (float*).
(long*): cast to type. Appled to &y it steamrolls over the information, that this is the address of a floating point typed object.
*: dereference, which means, "read out" whatever is located at the address given and interpret as the base type of the pointer that's being dereferenced. We've overwritten that to be (long*) and essentially are lying to the compiler.
For all intents and purposes this breaks pointer aliasing rules and invokes undefined behaviour. You should not do this (caveats apply¹).
The somewhat well defined way (at least it doesn't break pointer aliasing rules) to do such trickery is by means of a union.
float Q_rsqrt( float number )
{
union {
float y;
long i;
} fl;
float x2;
const float threehalfs = 1.5F;
x2 = number * 0.5F;
fl.y = number;
fl.i = 0x5f3759df - ( fl.i >> 1 ); // ???
fl.y = fl.y * ( threehalfs - ( x2 * fl.y * fl.y ) ); // 1st iteration
// fl.y = fl.y * ( threehalfs - ( x2 * fl.y * fl.y ) ); // 2nd iteration, this can be removed
return fl.y;
}
EDIT:
It should be noted, that the type-punning via union as illustrated above is not sanctioned by the C language standard as well. However unlike language undefined behavior the standard so far leaves the details of the kind of union accesses done in that way as implementation dependent behavior. Since type-punning is something required for certain tasks, I think a few proposals had been made to make this well defined in some upcoming standard of the C programming language.
For all intents and purposes practically all compilers support the above scheme, whereas type-punning via pointer casts will lead to weird things happening if all optimization paths are enabled.
1: Some compilers (old, or custom written, for specific language extensions – I'm looking at you CUDA nvcc) are severly broken and you actually have to coerce them with this into doing what you want.
OK, so you are looking at some ancient hackery from the time when floating point processors were either slow or non-existent. I doubt the original author would defend continuing to use it. It also doesn't meet the modern language transparency requirements (i.e. it is "Undefined behaviour") so may not be portable to all compilers or interpreters, or handled correctly by quality tools such as lint and valgrind, etc, but it was the way fast code was writ in the 80s and 90s.
At the bit level, everything is stored as bytes. A long is stored in 4 bytes, and a float is also stored in 4 bytes. However the bits are treated very differently. In integer/long, each bit is ranked similarly as a power of 2, and can be used as a bit field. In float, some bits are used to represent an exponent that is applied to the rest of the number. For more info read up on IEEE.
This trick takes the float value, and looks at the bytes as if it is an integer bit field, so then it can apply magic. The it looks at the resultant bytes as if they are a float again.
I have no idea what that magic is exactly. No-one else does, probably not even the guy who wrote it, as it isn't commented. On the other hand the doom and quake source did used to be cult code reading, so perhaps someone remembers the details?
There used to be many such tricks in the "good old days", but they are relatively unnecessary now, as floating point is now built in to the main processor and is as fast, and sometimes faster than, the integer operations. Originally, even uploading and downloading small ints from the co-processor could be done more quickly using such hacks than using the built-in methods.

Invalid narrowing conversion from "float" to "int"

I am using the SFML graphics library for C++. My compiler is Visual Studio 2017.
When I was making the function scale I encountered a problem. I had an error saying:
Invalid narrowing conversion from "float" to "int"
So, I put roundf in front of both items in the vector, but this didn't seem to help. Changing the std::vector<int> to std::vector<float> for the return value seems to work but I would like it as an integer. Any ideas? Here's my code:
std::vector<int> scale(sf::RenderWindow *Window, std::vector<int> offset)
{ // Scale objects
float scale = 500;
return { roundf(Window->getSize().x / scale * offset[0]), roundf(Window->getSize().y / scale * offset[1]) };
}
You want lroundf() to convert to a long int rather than round() which returns a float. You may also need to cast the result of lroundf() to int (because that is usually narrower than long).
Like this:
return { int(lroundf(Window->getSize().x / scale * offset[0])), int(lroundf(Window->getSize().y / scale * offset[1])) };

Why am I getting NaN when I should be getting a double?

My problem is somewhere in the definition of first_x and second_x. When I call the quad_eq function, I get a -nan(ind) return based on the code below. If I change the .pushback() method parameter to be a literal integer, I get that integer returned instead of NaN. This leads me to believe that the problem is with my calculation/definition of first_x and second_x. Maybe there is some trick to C++ that I am not seeing or understanding. Can anyone see what my problem is? (If this helps I am working out of Bjarne Stroustrup's C++ Principles and Practice Using C++ where he gives me the std_lib_facilities.h file to use as I do not understand headers yet)
vector<double>quad_eq(double a, double b, double c) {
vector<double>answers;
double first_x = (-b + sqrt((b * 2) - (4 * a * c))) / 2 * a;
double second_x = (-b - sqrt((b * 2) - (4 * a * c))) / 2 * a;
answers.push_back(first_x);
answers.push_back(second_x);
return answers;
}
Depending on the input, you are taking the square root of negative numbers, so you get NaN (which is, in fact, a double) out of that, and any other operations propagate that.
Sidenote: the code you show doesn't compile as-is, because it is missing #include <vector> and using namespace std;. The latter is also usually frowned upon.

Function 'deg2rad' could not be resolved

I am receiving an error because of the following code :
const double angle = deg2rad(180);
The error says:
Function 'deg2rad' could not be resolved
I have recently installed 'Eclipse IDE for C/C++ Developers' and I have added -std=c++11 to Other flags at C/C++ Build/Settings/Tool Settings/GCC C++ Compiler/Miscellaneous
Any ideas what might be wrong?
The C++ standard library does not include a deg2rad function. You will need to create your own, or include a library which has one. An example of such a function is:
#include <cmath>
double deg2rad(double deg) {
return deg * M_PI / 180.0;
}
Note that M_PI is not actually part of the standard either, but is commonly included in the cmath header. If you are using Visual C++ you will need to define _USE_MATH_DEFINES to enable it.
There is no deg2rad() in the C++11 standard so, unless it's provided by some other library, you'll have to write your own. Something like this should do as a start:
double deg2rad (double degrees) {
return degrees * 4.0 * atan (1.0) / 180.0;
}
As per the above code, I normally leave micro-optimisations up to the compiler, such as letting it decide whether short functions should be inlined, or whether it will constant-fold the expression 4.0 * atan (1.0) / 180.0 into a single constant.
However, there may be a case in certain circumstances (such as if the compiler isn't as clever as the ones I use) to explicitly add the optimisations (keeping in mind that inline is a suggestion to the compiler rather than a demand):
inline double deg2rad (double degrees) {
static const double pi_on_180 = 4.0 * atan (1.0) / 180.0;
return degrees * pi_on_180;
}
C++ does not implement a deg2rad function, so you will need to write it by yourself.
inline double deg2rad(double deg)
{
return deg * M_PI / 180.;
}
Notice how we declare the function inline: This is because we don't want to waste extra assembly instructions setting up the call stack and jumping to the address of the function. When the function is inlined, it is substituted into the place it was called from. Note that inline is just advice to the compiler, and it is free to ignore it.

Is it always necessary to use float literals when performing arithmetic on float variables in C++?

I see a lot of C++ code that has lines like:
float a = 2;
float x = a + 1.0f;
float b = 3.0f * a;
float c = 2.0f * (1.0f - a);
Are these .0f after these literals really necessary? Would you lose numeric accuracy if you omit these?
I thought you only need them if you have a line like this:
float a = 10;
float x = 1 / a;
where you should use 1.0f, right?
You would need to use it in the following case:
float x = 1/3;
either 1 or 3 needs to have a .0 or else x will always be 0.
If a is an int, these two lines are definitely not equivalent:
float b = 3.0f * a;
float b = 3 * a;
The second will silently overflow if a is too large, because the right-hand side is evaluated using integer arithmetic. But the first is perfectly safe.
But if a is a float, as in your examples, then the two expressions are equivalent. Which one you use is a question of personal preference; the first is probably more hygeinic.
It somewhat depends on what you are doing with the numbers. The type of a floating point literal with a f or F are of type float. The type of a floating point literal without a suffix is of type double. As a result, there may be subtle differences when using a f suffix compared to not using it.
As long as a subexpression involves at least one object of floating point type it probably doesn't matter much. It is more important to use suffixes with integers to be interpreted as floating points: If there is no floating point value involved in a subexpression integer arithmetic is used. This can have major effects because the result will be an integer.
float b = 3.0f * a;
Sometimes this is done because you want to make sure 3.0 is created as a float and not as double.