C++ translated to objective-C - c++

I'm looking into translating some code from C++ to Objective C and I ran into an instance that contains a function with a const notation at the end. I'm quite rusty on C++ and I don't remember what this would represent (I have been googling though). I'd like to know how to force this over to Objective-C. Currently, here's what I have:
C++ code:
float RenderingEngine1::RotationDirection() const
{
float delta = m_desiredAngle - m_currentAngle;
if (delta == 0)
return 0;
bool counterclockwise = ((delta > 0 && delta <= 180) || (delta < -180));
return counterclockwise ? +1 : -1;
}
Objective-C:
-(float)getRotationDirection{
float delta = desiredAngle - currentAngle;
if (delta == 0) {
return 0;
}
bool counterclockwise = ((delta > 0 && delta <= 180) || (delta < -180));
float test = counterclockwise ? +1 : -1;
NSLog(#"%f",test );
return counterclockwise ? +1 : -1; //problem
}
Edit: found the error of my ways and it was just an addition problem somewhere else in the program ('I love the easy ones'). That being said, I do want to ensure that the const declaration will not interfere with any further issues and want to check to ensure whether or not there should be any declarations I need to make (such as singleton methods and such). Thank you guys for the answers!

const in c++ means that this method doesn't alter the state of the object, thus it may use just const methods, and it can't alter class variables unless they're declared mutable.
If your class is immutable, you can safely assume that every method you've declared is the equivalent of a const method.
However, since you aren't altering any ivar, you're "translating" the code properly (logically speaking), as you aren't mutating any ivar.
I don't see any particular problem with your code, there shouldn't be a syntax (neither semantic) error.
PS: That's not how you should compare floating point numbers, look here.

Related

Why would someone write an if condition containing a float like this?

I am looking through some code previously written by a senior developer in my company and I am curious about the reasoning behind the somewhat convoluted looking if statement they wrote (I would ask them directly if possible).
The code is intended to check if temperature readings from a sensor are valid. I believe negative readings were valid at the time, which explains the use of std::abs() and comparison of that to 0.000001 instead of just using temperature > 0, however I am unsure why they chose to subtract 0. as well. I have included a minimum working example, but the focus of my question is on why the statement includes the - 0. (just to convert float to a double? That seems to be what VSCode thinks it does) and if my assumption about needing to accept negative values while also needing to invalidate (very near) zero readings in the form of floats sounds correct.
#include <optional>
#include <iostream>
void check_temp(std::optional<float> prev_temp, float cur_temp){
if ((!prev_temp && std::abs(cur_temp - 0.) < 1e-6) ||
(prev_temp && std::abs(prev_temp.value() - cur_temp) > 100.0))
{
std::cout << "Temperature error detected!\n";
}
return;
}
int main(int argc, char const *argv[])
{
std::optional<float> prev_temp = std::nullopt;
float cur_temp = 0;
while(1){
std::cout << "Enter temp: ";
std::cin >> cur_temp;
check_temp(prev_temp, cur_temp);
prev_temp = cur_temp;
}
return 0;
}
And to be very clear, the specific line (condition) I am looking for clarification on is:
(!prev_temp && std::abs(cur_temp - 0.) < 1e-6)
clarification on:
(!prev_temp && std::abs(cur_temp - 0.) < 1e-6)
!prev_temp certainly tests if a previous temperature exist. Since it does not (in this clause), code continues "as if" previous temperature was zero. The subtraction with 0.0 instead of 0.0f is an oversight on the original programming. The same functionality and simpler code would have been std::abs(cur_temp - 0.0f) for illustrative purposes.
There is no reason for a double constant 1.0e-6 except for a pedantic compare against 1.0e-6 vs 1.0e-6f - which are different values. IOWs, 1.0e-6f < 1.0e-6 might be true, so the equivalent replacement is std::abs(cur_temp) <= 1e-6f - note the <=.
The compare against the double 100.0 again is weak programming. Nothing gain by using double. It might not emit different code had is been 100.f with a good optimizing compiler.
IMHO
if ((!prev_temp && std::abs(cur_temp - 0.) < 1e-6) ||
(prev_temp && std::abs(prev_temp.value() - cur_temp) > 100.0))
better as
if ((!prev_temp && std::abs(0.0f - cur_temp) < 1e-6f) ||
(prev_temp && std::abs(prev_temp.value() - cur_temp) > 100.0f))
The only reason I see for masterfully coding in this fashion is to try to steer the compiler output. Such coding applies to the compiler of that vintage. Better now to code for clarity.

c++ program how can I return my array or write to a global variable

I am new with C++ and I have to write code, but somehow it is not working and I do not know what I can change. I would like to give back the array Grad, but it says segmentation fault (core dumped).
Could somebody help me with what I have to change?
Or is it possible to have a global variable and write from the function
directly to the global variable?
Thanks for your help.
Code:
double* Gradient(const double x[], int n1) {
double Grad [n1*4] = {0};
// We calculate the overlap. If the overlap is zero, the gradient
// is also zero. This should be probably improved in the future.
//int n = sizeof(x)/32;
for (int i = 0; i < n1*4; i++)
{
for (int j = 0; j < n1*4; i++)
{
if (i != j)
{
//cout << x[i]<< endl;
double xmin = max(x[i*4], x[j*4]);
double xmax = min(x[i*4+1], x[j*4+1]);
//if (xmin > xmax) return Grad;
double ymin = max(x[i*4+2], x[j*4+2]);
double ymax = min(x[i*4+3], x[j*4+3]);
//if (ymin > ymax) return Grad;
double x_overlap = xmax-xmin;
double y_overlap = ymax-ymin;
// Gradient for xmin
if (x[i*4] >= x[j*4] && x[i*4] != x[j*4+1] && x[i*4+1]
!= x[j*4] && x[i*4+2] != x[j*4+3] && x[i*4+3] != x[j*4+2]) Grad[i*4] =
Grad[i*4]-y_overlap;
// Gradient for xmax
if (x[i*4+1] < x[j*4+1]) Grad[i*4+1] = Grad[i*4+1] +
y_overlap;
// Gradient for ymin
if (x[i*4+2] >= x[j*4+2] && x[i*4] != x[j*4+1] &&
x[i*4+1] != x[j*4] && x[i*4+2] != x[j*4+3] && x[i*4+3] != x[j*4+2])
Grad[i*4+2] = Grad[i*4+2]-x_overlap;
// Gradient for ymax
if (x[i*4+3] <= x[j*4+3]) Grad[i*4+3] = Grad[i*4+3] +
x_overlap;
// Gradient for xmax if rectangles are touching by the
x-coordinate
if (x[i*4+1] == x[j*4] && x[i*4+3] > x[j*4+2] &&
x[i*4+2] < x[j*4+3])
{
Grad[i*4+1] = Grad[i*4+1] + y_overlap;
}
// Gradient for ymax if rectangles are touching by the
y-coordinate
if (x[i*4+3] == x[j*4+2] && x[i*4+1] > x[j*4] && x[i*4]
< x[j*4+1])
{
Grad[i*4+3] = Grad[i*4+3] + x_overlap;
}
}
}
}
return Grad;
}
int main() {
// Coordinates of the rectangles
double x[] = {0,6,0,9,3,9,4,11};
int n1 = sizeof(x)/32;
double gradient;
gradient = Gradient(x,n1);
cout << "Gradient R1 xmin = " << Gradient[0] << endl;
}
Arrays are not first class elements in C++ language (they were not in C either). Specifically, when you pass an array to a function, or when you return it, it decays to a pointer to its first element. As the Grad array has automatic storage (neither static nor allocated) its lifetime ends at the end of a function and you only return a dangling pointer, meaning a pointer to a variable whose lifetime has ended. Using it is explicitely Undefined Behaviour.
In common implementation, automatic variables are allocated in the stack. So after the function returns, the memory pointed to by the dangling pointer is likely to be reused and what you will get will not be what you would expect. The segmentation fault is just one of the possible consequences of the UB.
The common way to return an array if you do not intend to use multi-threading would be to declare it static. That way its lifetime extends up to the end of the program and it solves the dangling pointer problem. That would be fine for a static size array (size defined at compile time) but not for a dynamic size (defined at run time). So you are left with 2 C-ish ways:
use a dynamically allocated array (with new[] or malloc); the caller will then have to free it (with resp. delete[] or free)
let the caller manage the array and pass it to the function (void Gradient(const double x[], double *Grad, int n1)). This is the prefered way because the caller has full control over the allocation mode.
But in C++ the idiomatic way is to use a vector: std::vector Grad(n1*4, 0.);. A vector is a true C++ object and can be assigned or returned. Unless you have strong reasons to do so, avoid C-ish ways because C++ containers are much more programmer friendly.
how can I return my array or write to a global variable
Read a good book on C++ programming, and look into this C++ reference.
double* Gradient(const double x[], int n1) {
double Grad [n1*4] = {0};
If n1 is a large positive integer such as 1234567, your code is likely to have a stack overflow. If n1 is negative, you are in trouble. AFAIK, VLAs are not in C++.
Read also how to debug small programs
You probably want to use some standard C++ container. std::array or std::vector comes to mind.
You can return some std::array<int,10>. Of course the computer would copy ten integers, and that is slower than returning just a pointer.
In some cases, you might want to use smart pointers. Read about the standard <memory> header.
Beware of buffer overflow and segmentation fault and other kinds of undefined behavior.
If you compile your C++ code with a recent GCC compiler, enable all warnings and debug info, so use g++ -Wall -Wextra -g. If you use GCC 10, consider using the recently added static analysis options. If you prefer Clang, consider using its static analyzer. Consider also using the Frama-C analyzer and reading this draft report. Be however aware of Rice's theorem.
In all cases read the documentation of your particular C++ compiler. Don't confuse your C++ compiler with your IDE or source-code editor. I suggest to compile on the command line, and use some build automation tool (perhaps GNU make or ninja) with some version control tool such as git, and some debugger such as GDB. Tools like valgrind are also helpful.
Always avoid returning the address of some automatic variable on the call stack. Once your function returned, that address is invalid. Be scared of uninitialized pointer variables.
I will try to help you
variable-sized array double Grad [n1*4] = {0}; In C++, variable length arrays are not legal. G++ allows this as an "extension".
return Grad; return pointer to local data, after exiting function Gradient Grad id not available
You can use std::vector, thus your code may look like this:
std::vector<double> Gradient(const double x[], int n1) {
std::vector<double> Grad (n1*4, 0);
...
Grad[i*4+3] = ...
...
return Grad;
}
There are multiple problems with your code.
You can't allocate the size of a static array at run time , that is you can't do this operation double Grad [n1*4] = {0};
where n1 is a variable. To allocate memory you have to use malloc function.
ptr = (int*)malloc(n * sizeof(int));
where n is the size of desired array.A continuous block of memory will be allocated
Array can't be returned as such, to solve that problem pointers are introduced.
If you follow the above method, ptr is a pointer which can access a memory location,while to access a particular element you can simple use ptr[i], where i is the desired index
Gradient is a function, it's illegal to perform this operation Gradient[0].
I hope this have cleared your doubt. A simple tip try writing small block of code to check if certain thing works.

More general test for same order of magnitude than comparing floor(log10(abs(n)))

I am implementing an optimization algorithm and have diferent heuristics for cases where no or largely different lower and upper bounds for the solution are known or not.
To check, my first approach would be simply taking
if(abs(floor(log10(abs(LBD))) - floor(log10(abs(UBD)))) < 1 )
{ //(<1 e.g. for 6, 13)
//Bounds are sufficiently close for the serious stuff
}
else {
//We need some more black magic
}
But this requires previous checks to be gerneralized to NAN, ±INFINITY.
Also, in the case where LBD is negative and UBD positive we can't assume that the above check alone assures us that they are anywhere close to being of equal order of magnitude.
Is there a dedicated approach to this or am I stuck with this hackery?
Thanks to geza I realized that thw whole thing can be done without the log10:
A working solution is posted below, and a MWE including the log variant posted on ideone.
template <typename T> double sgn(T val) {
return double((T(0) < val) - (val < T(0)))/(val == val);
}
bool closeEnough(double LBD, double UBD, uint maxOrderDiff = 1, uint cutoffOrder = 1) {
double sgn_LBD = sgn(LBD);
double sgn_UBD = sgn(UBD);
double cutoff = pow(10, cutoffOrder);
double maxDiff = pow(10, maxOrderDiff);
if(sgn_LBD == sgn_UBD) {
if(abs(LBD)<cutoff && abs(UBD)<cutoff) return true;
return LBD<UBD && abs(UBD)<abs(LBD)*maxDiff;
}
else if(sgn_UBD > 0) {
return -LBD<cutoff && UBD<cutoff;
}
// if none of the above matches LBD >= UBD or any of the two is NAN
}
As a bonus it can take cutoffs, so if both bounds lie within [-10^cutoffOrder,+10^cutoffOrder] they are considered to be close enough!
The pow computation might also be unecessary, but at least in my case this check is not in a critical code section.
If it would be, I suppose you could just hard code the cutoff and maxDiff.

Coordinate left-right-up-down in C++

I'm making a pan-tilt tracking camera like this, before control servos, I have to know where object is ( up-left, up-right, down-left, down-right), I've tried
if ( x > 350) {
move_right();
}
else if (x < 290) {
move_right();
}
if ( y > 206) {
move_up();
}
else if ( y < 126) {
move_down();
}
But I think it's looked weird. Is there any method simple like switch statement?? My code is written in C++ and OpeCV libraries
The switch statement uses exact values and not inequalities. It won't be of any use for you.
I don't know if you really need the "else-if". Also, what happens when x is between 290 and 350?
If you can keep the comparison operator the same, you could create a lookup table of .

Stuck in Infinite Recursion

I have this function to solve a maze in C++, but when I run the program I get a Bad Access Error in the recursion. I think in may be an infinite loop. I have no idea where and what is going wrong.
bool Solve_Maze(int coorx,int coory) {
if((Map[coorx][coory]==Start)||(Map[coorx][coory]==path)) {
Map[coorx][coory]=wall;
Solve_Maze(coorx+1,coory);
Solve_Maze(coorx-1,coory);
Solve_Maze(coorx,coory+1);
Solve_Maze(coorx,coory-1);
}else if(Map[coorx][coory]==End) {
cout<<"You Solved the Maze!"<<endl;
delete Map;
return(true);
}
}
1) You are not returning any value in if statement
2) Map[coorx][coory] always assigned to wall in all function call..Does wall refers to a global state?
I changed the function to return void since the value wasn't properly being returned up the stack. In this case you will just use the global found variable to check if the end was found. (this will require you to set 'found = false' every time before you run the function).
bool found = false;
You also want to do some input validation
if( coorx > maxX || coorx < 0 || coory > maxY || coory < 0) return;
You will need to replace maxX and maxY with 1 more than your maximum values for coorx and coory. That will ensure you don't get a bad access error.
bool found = false; // this will be global scope or pass it by reference
Solve_Maze(x,y);
// if(found) - found will be true if you found the end
void Solve_Maze(int coorx,int coory) {
if( coorx > maxX || coorx < 0 || coory > maxY || coory < 0) return;
else if(((Map[coorx][coory]==Start)||(Map[coorx][coory]==path))) {
Map[coorx][coory]=wall;
Solve_Maze(coorx+1,coory);
Solve_Maze(coorx-1,coory);
Solve_Maze(coorx,coory+1);
Solve_Maze(coorx,coory-1);
}else if(Map[coorx][coory]==End) {
cout<<"You Solved the Maze!"<<endl;
delete Map;
found = true;
}
}
Run it in a debugger (gdb or dbx). Compile with the -g flag so your program can be debugged. If you don't know how to use a debugger, google "dbx cheatsheet." You can isolate where it's stuck in the loop (if your guess is right) and step your way through. The total time it will take you to become proficient enough in a debugger to do this is, and to actually do it, is less than the amount of time you have spent thinking about it already.
No sarcasm is intended - people really do often overestimate the work in learning a debugger, so I want to really assert the point that it's worth it even for a simple problem, and tremendously pays off for big problems.