• Hey, guest user. Hope you're enjoying NeoGAF! Have you considered registering for an account? Come join us and add your take to the daily discourse.

C++ Help?

Status
Not open for further replies.
maharg said:
Most of the real harm goto can do is fairly restricted from actually happening, since you can't directly do a long jump. Gotos have only one solid use in C as far as I'm concerned, though: Complex resource cleanup scenarios. In C++ even that use case is pretty much eliminated through the use of RAII.
I've used goto often as a means to break from multiple nesting levels inside a loop. People use break all the time and don't think twice about it, so it's not that much of a stretch to imagine useful scenarios where you want to break out of TWO enclosing loops, not just one. People will say "yea but you can do that by putting your loop inside a function and then returning from the middle of the function", or "make an additional loop termination condition and set it to true", or any number of other ways of solving the same problem. But to me, the goto requires the least amount of code and is the most self-documenting.

One reason people can't ever seem to come up with good use cases for goto is that they remove it from their mind and don't think about it because they were trained not to. If you start looking for cases where goto is honest-to-god the best way to do something, you might actually be surprised.
 

Chichikov

Member
cpp_is_king said:
How am I wrong about exceptions? I'm not saying that you're wrong, I just don't know specifically what part you think I'm wrong about
When using structured exception handling you're still dealing with a well defined code flow.
When you throw gotos into the mix, your code is at the mercy of the jump statements, as you can really jump anywhere and at any time.
No code can be hardened against that.

And again, there are certain cases where it make sense, and you can try to localize the use, but you never know what the future brings, and that code is not going to play well with others.

In theory it can work, but let me tell you this, I had to make some old hacky code (that actually had very good reason to be written that way) with modern software, and that ain't fun to do in the real world.

Take this as an advice, if you're writing serious code, think REALLY REALLY well before you start to use gotos.
 

Fafalada

Fafracer forever
maharg said:
Something being useful is not the same as it being usable as a standard tool.
Which makes goto potential evil less of an issue then some others.
Macros are often labeled as evil too and not only they have genuine practical uses, most of their 'evil' stems from the fact that most C++ toolchains are at least 2 decades outdated.
 
Chichikov said:
When using structured exception handling you're still dealing with a well defined code flow.
When you throw gotos into the mix, your code is at the mercy of the jump statements, as you can really jump anywhere and at any time.
No code can be hardened against that.

Actually it can only jump anywhere within a single function at any time. And not actually anywhere, but only to sequence points.
 

wolfmat

Confirmed Asshole
The point of advising against GOTO is pointing out that your written code, the code that you produce, will inevitably suffer from literal GOTOs in many ways, two of which are reduced readability and confusing program flow. If they're aliased in the form of a switch statement, for instance, then everybody knows what's gonna happen by reading your code; it's not a bunch of GOTOs, it's a switch statement, that's pretty easy to get. Same with procedures and shit. Of course the generated assembly contains GOTOs, JMPs, JNEs, JNZs... That's besides the point.

Edit: An isolated GOTO in inline assembly that stays in scope is not a dealbreaker, by the way. Just don't build selfreferential code based on GOTOs, don't build big chunks of code with lots of GOTOs, don't expose GOTO targets to the world without care, don't make assumptions about the GOTO's destination unless it's pretty much written in stone (something like "GOTO somelabel" once is cool if it makes your snippet blazingly fast and the label is unambiguous and in short reach, for example). Otherwise, good luck finding a job.
 

maharg

idspispopd
Fafalada said:
Which makes goto potential evil less of an issue then some others.
Macros are often labeled as evil too and not only they have genuine practical uses, most of their 'evil' stems from the fact that most C++ toolchains are at least 2 decades outdated.

Macros in C++ are a mess. The only difference between an out of date and an up to date C++ toolchain in terms of macros is that the up to date one makes it possible to do most of the things your average programmer needs them for doable with inline functions. And the only reason a lot of C++ programmers seem unwilling to use unbound inline functions is because they were taught that OO is the only way and that everything needs to be encapsulated. Which is a philosophy best left to Java.

In the end, good C++ (to me) barely resembles C. I've spent a lot of time programming in both. I've found uses for goto and macros in C, but I've always found that in C++ in particular you're better off using the tools suited to the language and not the baggage from a whole different language.
 
maharg said:
Macros in C++ are a mess. The only difference between an out of date and an up to date C++ toolchain in terms of macros is that the up to date one makes it possible to do most of the things your average programmer needs them for doable with inline functions. And the only reason a lot of C++ programmers seem unwilling to use unbound inline functions is because they were taught that OO is the only way and that everything needs to be encapsulated. Which is a philosophy best left to Java.

In the end, good C++ (to me) barely resembles C. I've spent a lot of time programming in both. I've found uses for goto and macros in C, but I've always found that in C++ in particular you're better off using the tools suited to the language and not the baggage from a whole different language.

If you're writing multi-platform code, code that needs to build on multiple compilers, or code that needs to be enabled/disabled (i.e. literally non-existant in a binary) based on certain conditions, macros are the only solution. If you're writing very simple code though with a small audience I guess you don't have to worry about these types of issues. But in all the environments I've ever worked in, it's fairly critical.
 

maharg

idspispopd
Ah yes, clearly the reason I disagree with you about macros is because I've only ever worked on "very simple code for a small audience." Nicely done, you've completely disarmed me with your superior logic[al fallacy].

If we're through with that garbage, there's two kinds of things here and maybe I should have distinguished them and not been so hyperbolic.

Macros as a means to control compilation through #if and such for platform dependent or debugging chunks of code is obviously a necessity that will never go away. Even stuff like DEBUG() as a printf alias that's only on in debug builds isn't that bad.

Macros as a means of creating type aliases, or for defining actual execution flow (macro-functions), however, have alternate mechanisms in C++ that play nice with, for eg., type safety and namespaces -- both very common features of modern well written C++. If you're writing new code at this point, you are much much better off using those features for this sort of thing.
 
maharg said:
Ah yes, clearly the reason I disagree with you about macros is because I've only ever worked on "very simple code for a small audience." Nicely done, you've completely disarmed me with your superior logic.

I wasn't attempting to disarm you, my bad if it came across that way. I mean "you" in the indefinite sense. Anyway I was only stating that the problem macros solve and which they are most useful for is not really solveable any other way, and it's quite a common problem.
 

Linkhero1

Member
I'm trying to open a file called dictionary.txt and load it into an array. I'm having trouble getting this to compile. I'm pretty sure there are a lot of issues with my code. Any help would be kindly appreciated.

Code:
#include <iostream>
#include <fstream>
#include <string>
#define NUMBER_OF_WORDS 100366
#define MAX_WORD_LENGTH 25

using namespace std;

class Dictionary
{
public:
	 Dictionary();
	 ~Dictionary();
	 void sort();
	 void readwords();
	 void print() const;
private:
	char **words;
};

Dictionary::Dictionary()
{
	words = (char**)new(sizeof(char*),NUMBER_OF_WORDS);

}

Dictionary::~Dictionary()
{
	int i;
	for (i = 0; i < NUMBER_OF_WORDS; i++)
		delete(words[i]);
	delete(words);
}

void print() const
{
	cout << words[10] << endl;
	cout << words[20] << endl;
	cout << words[24] << endl;
}

void readwords(const char *filename)
{
	ifstream inStream; 
	int i;
	char buffer[MAX_WORD_LENGTH+1];

	inStream.open("dictionary.txt");
	if (inStream.fail())
	{
		cout << "Dictionary has failed to open.";
		exit(1);
	}
	
	for (i = 0; i < NUMBER_OF_WORDS; i++)
	{
		inStream >> buffer;
		words[i] = new char[strlen(buffer)+1];
		strcpy(words[i],buffer);
	}
		
	inStream.close();
}

int comparator(const void *str1, const void *str2)
{
	return strcmp(*(char**)str1,*(char**)str2);
}

int main(int argc, char *argv[])
{
	Dictionary dict;
	
	dict.readwords();

	dict.print();

	return 0;
}

edit: nvm fixed it and got it to compile. I'll ask later if I have any further issues.
 
Linkhero1 said:
I'm trying to open a file called dictionary.txt and load it into an array. I'm having trouble getting this to compile. I'm pretty sure there are a lot of issues with my code. Any help would be kindly appreciated.

Err.. Are you ok with having to recompile your code every time you add / remove a word from the dictionary? Why don't you just make it keep reading until it's done.
 

Linkhero1

Member
cpp_is_king said:
Err.. Are you ok with having to recompile your code every time you add / remove a word from the dictionary? Why don't you just make it keep reading until it's done.
Not sure if that's what I want though.
 
Err, I'm getting some strange errors on a file that worked before and now isn't (since moving to a new project)

Point.h
Code:
#ifndef POINT_H
#define POINT_H

#include <math.h>
#define OUT_OF_BOUNDS 1000

class Point
{
public:
	Point(double px=0, double py=0, double theta=0)
	{
		x=px;
		y=py;
		theta=0;
	}

	double getX()
	{
		return x;
	}

	double getY()
	{
		return y;
	}

	double getTheta()
	{
		return theta;
	}

	double dist(Point op)
	{
		return sqrt(pow(x-op.getX(),2) + pow(y-op.getY(),2));
	}

	void setVars(double nt=0)
	{
		theta=nt;
	}

	void setVars(Point np)
	{
		x=np.getX();
		y=np.getY();
		theta=np.getTheta();
	}

	void setVars(double nx, double ny)
	{
		x=nx;
		y=ny;
	}

	Point addPoint(Point op)
	{
		return Point(x+op.getX(),y+op.getY(), theta+op.getTheta());
	}

	bool outOfBounds()
	{
		return x>=OUT_OF_BOUNDS && y>=OUT_OF_BOUNDS;
	}

private:
	double x,y, theta;
};

#endif //POINT_H

I keep getting the errors

Code:
Error	3	error C2061: syntax error : identifier 'Point'		7
Error	4	error C2059: syntax error : ';'		7
Error	5	error C2449: found '{' at file scope (missing function header?)		8
Error	6	error C2059: syntax error : '}'		67
 
Zoramon089 said:
Err, I'm getting some strange errors on a file that worked before and now isn't (since moving to a new project)

The actual error is likely in another file, but it doesn't realize there's an error until you get to this file. Determine which .CPP file is giving you the error when compiled (you may only have 1 CPP file in your entire project in which case it would be obvious), then paste all the code up until the point that you do

#include <Point.h>
 
It was weird, it ended up being that I had to change how the project was being compiled. It was set to default and I had to change it to compile as a C++ project...something like that
 
Zoramon089 said:
It was weird, it ended up being that I had to change how the project was being compiled. It was set to default and I had to change it to compile as a C++ project...something like that

What's the filename of the CPP file? Is it .C? or something other than .CPP?
 
How would I go about casting a superclass down to a subclass?

Say I have something like


Code:
class A
{}

class B: public A
{}

class C: public A
{}

vector<A> listOfStuff;

What I want to do is to be able to put various subclass instances into listOfStuff but when looping through it, depending on the index (which I use to determine what subclass instance it is) I can cast that particular entry into a subclass and call it's functions.

When i simply try

Code:
B bInst = (B)listOfStuff[i];
Code:
IntelliSense: no suitable user-defined conversion from "A" to "B" exists
 

fenners

Member
Zoramon089 said:
How would I go about casting a superclass down to a subclass?

Say I have something like


Code:
class A
{}

class B: public A
{}

class C: public A
{}

vector<A> listOfStuff;

What I want to do is to be able to put various subclass instances into listOfStuff but when looping through it, depending on the index (which I use to determine what subclass instance it is) I can cast that particular entry into a subclass and call it's functions.

When i simply try

Code:
B bInst = (B)listOfStuff[i];
Code:
IntelliSense: no suitable user-defined conversion from "A" to "B" exists

Well, is the stuff in the list actually of Class A or class B?
 
fenners said:
Well, is the stuff in the list actually of Class A or class B?

It's actually of class B or C. Nothing in the list is of class A. The reason I wanted them all to be in 1 list is because there's a lot of common functions in the superclass that I call every iteration, but sometimes I want to call a subclass specific function.

I wanted it so i wouldn't have to have multiple structures (like separate vectors of B and C) that I'd have to loop through, and only had to deal with 1
 

fenners

Member
Zoramon089 said:
It's actually of class B. The reason I wanted them all to be in 1 list is because there's a lot of common functions in the superclass that I call every iteration, but sometimes I want to call a superclass specific method.

I wanted it so i wouldn't have to have multiple structures (like separate vectors of B and C) that I'd have to loop through, and only had to deal with 1

Ok, I gotcha.

Code:
B bInst = (B)listOfStuff[i];

Is that the actual code or just psuedo code? if it's not, what are you actually doing because as written, you're creating a copy of listOfStuff, if I'm reading it correctly.
 
fenners said:
Ok, I gotcha.

Code:
B bInst = (B)listOfStuff[i];

Is that the actual code or just psuedo code? if it's not, what are you actually doing because as written, you're creating a copy of listOfStuff, if I'm reading it correctly.


Code, with the actual class name replaced with B, but it follows the same structure I outlined above. It keeps giving me that error

I'm just getting listOfStuff and index i. Imagine it's in a for loop going through listOfStuff

Code:
for(i=0; i<listOfStuff.size(); i++)
{
     listOfStuff[i].superclassfunc();

     if(i==0) 
     {
          B bInst = (B)listOfStuff[i];
          // Do stuff with B
     }
     else
     {
          C cInst = (C)listOfStuff[i];
          // Do stuff with C
     }
}
 

AcciDante

Member
It looks like you might want a vector of base class pointers that point to the objects. I think you'd have to then worry about virtual member functions, or you'd have to convert the base class pointers into their respective class pointer to call functions. If you cast a subclass to a superclass you have to worry about object slicing (losing data not in the subclass).

Hopefully that helps a little. I'm in class right now on my phone. :/
 

poweld

Member
Zoramon089 said:
How would I go about casting a superclass down to a subclass?

Say I have something like


Code:
class A
{}

class B: public A
{}

class C: public A
{}

vector<A> listOfStuff;

What I want to do is to be able to put various subclass instances into listOfStuff but when looping through it, depending on the index (which I use to determine what subclass instance it is) I can cast that particular entry into a subclass and call it's functions.

When i simply try

Code:
B bInst = (B)listOfStuff[i];
Code:
IntelliSense: no suitable user-defined conversion from "A" to "B" exists
Just so you know, the correct (as far as I've ever read it) terminology here is base class and derived class. A is the base class of derived class B.

Onto the question, if you're trying to copy from the base to a derived class, instead of casting to B, you're going to need to either create a B::eek:perator=(const A& base) function to copy, or a B::B(const A& base) function to construct. Otherwise, the compiler will not know how to construct or copy the data for your bInst object.

edit:

With your latest update I can see what you're trying to do. What you want is a vector of pointers to instances of your base class. If you push_back new'ed instances of your derived classes into this vector, all you have to do to "get back to" the derived class is perform a nice safe dynamic_cast<derived> and performed your derived operations then.
 
How would I write that? I'm a little confused. So I made listOfStuff a vector of points (i.e. vector<B>* listOfStuff) but I don't know how to perform the cast. Currently I have...

Code:
 B Binst = dynamic_cast<B*>(listOfStuff[i])
 

fenners

Member
Zoramon089 said:
How would I write that? I'm a little confused. So I made listOfStuff a vector of points (i.e. vector<B>* listOfStuff) but I don't know how to perform the cast. Currently I have...

Code:
 B Binst = dynamic_cast<B*>(listOfStuff[i])

You need a pointer.

Code:
 B* Binst = dynamic_cast<B*>(listofStuff[i])
 

poweld

Member
fenners said:
You need a pointer.

Code:
 B* Binst = dynamic_cast<B*>(listofStuff[i])
Right, and listofStuff is a vector<A*>

Think of it using one of the class analogies - I like cars.

Class A is "Car"

Class B is "Truck" and is a "Car" due to public inheritance

Class C is "Sedan" and is a "Car" for the same reason

Create a vector of Car pointers. Into that vector you push back some Truck and some Sedan pointers. This makes sense because your container is for Cars, and that's what you're putting into it. When you want to do truck specific operations on a truck within that list, you cast it as a truck by a dynamic_cast, like dynamic_cast<Truck*>cars. If the pointer returned by the dynamic_cast is NULL, the object wasn't in fact a Truck... it may have been just a Car, or a Sedan. If it succeeds, you'll have a Truck* you can work with.
 
Anyone know how to properly convert from float to double? I have one variable that as a float is something like 3.4 but as a double it's some large number like 9523243234242324 and I don't understand why that's happening...or is possible

I do double num = (double)floatNum but that doesn't seem to work
 

AcciDante

Member
Zoramon089 said:
Anyone know how to properly convert from float to double? I have one variable that as a float is something like 3.4 but as a double it's some large number like 9523243234242324 and I don't understand why that's happening...or is possible

I do double num = (double)floatNum but that doesn't seem to work
Hmm, I thought float to a double would be considered promotion and would be converted implicitly...Anyone know?
 

dogmaan

Girl got arse pubes.
Zoramon089 said:
Anyone know how to properly convert from float to double? I have one variable that as a float is something like 3.4 but as a double it's some large number like 9523243234242324 and I don't understand why that's happening...or is possible

I do double num = (double)floatNum but that doesn't seem to work

Code:
template <typename T, typename X>
convert(T t, X x)
{
    stringstream databuffer;
    databuffer << t;
    databuffer >> x;
    return x;
}

double d = 5;
float f = 0;

f = convert(d, f);

would this work? (not tested, probably shitty)

or just static_cast<double> floatnum?
 

Lathentar

Looking for Pants
Zoramon089 said:
Anyone know how to properly convert from float to double? I have one variable that as a float is something like 3.4 but as a double it's some large number like 9523243234242324 and I don't understand why that's happening...or is possible

I do double num = (double)floatNum but that doesn't seem to work
double num = static_cast<double>( floatNum );

That work for you?
 
Nope, none of those work. What's strange is that given the same float it returns different double values...this is such a weird problem
 

Zoe

Member
Are you positive the float has what you're expecting it to have?

Otherwise, I think my half-assed way of dealing with things like this was doing
double result = 1.0 * floatNum
:lol
 
Zoe said:
Are you positive the float has what you're expecting it to have?

Otherwise, I think my half-assed way of dealing with things like this was doing
double result = 1.0 * floatNum
:lol

Yeah, i have it print out the float and the float converted to a double and the float is correct but the double isn't...

Is there anyway to convert a float to a string? Then I could convert that to a double easily
 

fenners

Member
Zoramon089 said:
Yeah, i have it print out the float and the float converted to a double and the float is correct but the double isn't...

Let's see a code sample.

Code:
double num = static_cast<double>( floatNum );

Because that should absolutely work. How are you printing out your num (as a double) to see what it contains? I know when I mess up floats/unsigned ints in my printfs, I get those weird big ints...
 
Okay, so I changed the function itself to return a double, but it only shows the right value when printed as a float...

Code:
static double getMarkAngle(double(*trans)[4])
{
	GLdouble		m_modelview[16];
	double			val1, val2;
        
	argConvGlpara(trans,m_modelview);

	val1 = m_modelview[1];
	val2 = m_modelview[5];
	return (180/M_PI*atan2(-val1,val2));
}


Code:
printf("float: %f  double: %d \n", getMarkAngle(object[i].trans), getMarkAngle(object[i].trans));

Code:
float: 93.145900  double: 1811134451
 

fenners

Member
Change that 180 to 180.0f.

%d is decimal integer BTW. That's your problem.

Cplusplus.com has a good guide - that's a handy C++ reference for C++/STL etc, quicker to navigate & more to the point than the Visual Studio web/help in most cases where you're just checking syntax etc.
 
fenners said:
Change that 180 to 180.0f.

%d is decimal integer BTW. That's your problem.

Cplusplus.com has a good guide - that's a handy C++ reference for C++/STL etc, quicker to navigate & more to the point than the Visual Studio web/help in most cases where you're just checking syntax etc.

242vfk2.jpg



That fixed it...and I screwed up in another function which was also causing errors. Basically...FML. Debugging never gets less painful no matter how many times you have to do it
 

dogmaan

Girl got arse pubes.
Zoramon089 said:
Yeah, i have it print out the float and the float converted to a double and the float is correct but the double isn't...

Is there anyway to convert a float to a string? Then I could convert that to a double easily

Code:
class BadConversion : public std::runtime_error {
 public:
   BadConversion(std::string const& s)
     : std::runtime_error(s)
     { }
 };

 template<typename T>
 inline std::string stringify(T const& x)
 {
   std::ostringstream o;
   if (!(o << x))
     throw BadConversion(std::string("stringify(")
                         + typeid(x).name() + ")");
   return o.str();
 }

string blah = stringify(double blah);
 

Linkhero1

Member
I'm having trouble understanding what this is

typedef enum Node {A,B,C,D,E,F,G,H} Node;

is it a more simple way of creating a struct? I just can't imagine how it would look like as a struct.

Also I'm trying to run this but I keep getting error "Cannot convert from int to Node"

Code:
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

const int INFINITY = 9999;
const int UNDEFINED = -1;
const int NODES = 8;

using namespace std;

typedef enum Node {A,B,C,D,E,F,G,H} Node;

Node findVertexInQWithSmallestDist(const Node Q[], const int dist[])
{
	int i;
	Node nodeWithSmallestDist;
	
	for (i = 0; i < NODES; i++)				// Find any node to set as the node having the smallest
		if (Q[i] != -1)						//	distance from the source. I set the first node.
		{
			nodeWithSmallestDist = i;
			break;
		}
	
	for (i = 0; i < NODES; i++)							// find the actual node with the smallest
		if (Q[i] != -1)									//	distance from the source
			if (dist[i] < dist[nodeWithSmallestDist])
				nodeWithSmallestDist = i;
	
	return nodeWithSmallestDist;
}

void removeNodeFromQ(Node Q[], Node u)
{
	Q[u] = -1;											// marks the node as removed
}

int distanceBetweenNodes(const int graph[][NODES], Node u, Node v)
{
	return graph[u][v];
}

void printShortestPath(const Node prev[], Node dest, int cost)
{
	Node path[NODES];
	Node currentNode;
	int i = 0;
	int j;
	
	path[i++] = dest;
	for (currentNode = dest; prev[currentNode]+'A' != '@'; i++)		// special marker to indicate the starting path
	{
		path[i] = prev[currentNode];
		currentNode = prev[currentNode];
	}
	
	cout << "Cost: " << cost << endl;
	for (j = i-1; j >= 0; j--)
		cout << "Path: " << path[j]+'A';
}

void findShortestPath(const int graph[][NODES], Node src, Node dest)
{
	int v;
	int alt;
	int dist[NODES] = {INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY};			// dist[v] = infinity
	Node prev[NODES] = {UNDEFINED,UNDEFINED,UNDEFINED,UNDEFINED,UNDEFINED,UNDEFINED,UNDEFINED,UNDEFINED};	// prev[v] = undefined
	Node Q[NODES] = {A,B,C,D,E,F,G,H};					// Q = set of all nodes in the graph
	Node u;
	int numberOfNodesLeft = NODES;
	
	dist[src] = 0;										// dist[source] = 0
	while (numberOfNodesLeft > 0)						// while Q is not empty
	{
		u = findVertexInQWithSmallestDist(Q,dist);
		if (u == INFINITY)
			break;
		
		removeNodeFromQ(Q,u);							// remove node u from Q
		numberOfNodesLeft--;
	
		for (v = 0; v < NODES; v++)						// for each POSSIBLE neighbor v of u
			if (Q[v] != -1 && graph[u][v] > 0)			// if v is still in Q and is a neighbor of u,
			{											//	it has a weight
				alt = dist[u] + distanceBetweenNodes(graph,u,v);
				if (alt < dist[v])
				{
					dist[v] = alt;
					prev[v] = u;
				}
			}
	}
	
	printShortestPath(prev,dest,dist[dest]);
}

int main(int argc, char *argv[])
{
	ifstream inStream;
	int graph[NODES][NODES];
	int i;
	int j;
	char _src;
	char _dest;
	Node src;
	Node dest;

	inStream.open("graph.txt");
	if(inStream.fail())
	{
		cout << "Graph has failed to open";
		exit(1);
	}

	for (i = 0; i < NODES; i++)
		for (j = 0; j < NODES; j++)
			inStream >> graph[i][j];
	
	inStream.close();
	
	cout << "Enter start point: ";
	cin >> _src;
	cout << endl;
	cout << "Enter end point: ";
	cin >> _dest;
	
	_src = toupper(_src);
	_dest = toupper(_dest);
	src = _src - 'A';
	dest = _dest - 'A';
	
	findShortestPath(graph,src,dest);
	
	return 0;
}
 

poweld

Member
Linkhero1 said:
I'm having trouble understanding what this is



is it a more simple way of creating a struct? I just can't imagine how it would look like as a struct.

Also I'm trying to run this but I keep getting error "Cannot convert from int to Node"
An enum is a simple way of creating a series of numbers assigned to values. The point of them is to avoid using "magic numbers". By default, when you define an enum the values begin at 0 and increment by one thereafter. So, A=0, B=1, C=2, etc.

However, they are not like int's in the sense that they do not implicitly convert from any other type (int, double, etc).
Code:
typedef enum Node { A, B, C } Node;
int i = A; // OK
Node j = i; // Won't compile - int does not implicitly convert to Node
 

malsumis

Member
anybody did cuda here? I'm doing a radix-4 fft implementation here, and it falls apart. It is numerically correct, it does work on a CPU. When I tweaked it to execute on CUDA, it almost works, since the resulting image is all jagged up. Please help, anyone?

PS: I'm reordering the output outside of the kernel.

Code:
//re_s is the real part of the signal
//im_s is the imaginary part of the signal
//p is the number of stages of decimation
//N is the signal length
//kernel assumes that the signal is indexed from 1.

#include "math.h"

#ifndef PI
#define PI           3.14159265358979
#endif

struct cuComplex {
float r;
float i;
cuComplex( float a, float b ) : r(a), i(b) {}
__device__ float magnitude2( void ) {
return r * r + i * i;
}
__device__ cuComplex operator*(const cuComplex& a) {
return cuComplex(r*a.r - i*a.i, i*a.r + r*a.i);
}
__device__ cuComplex operator+(const cuComplex& a) {
return cuComplex(r+a.r, i+a.i);
}
__device__ cuComplex operator-(const cuComplex& a) {
return cuComplex(r-a.r, i-a.i);
}
};


__global__ void radix(float *re_s, float *im_s,  int p ,int N) {
	
	
int n=blockIdx.x * blockDim.x + threadIdx.x;
int iy=blockIdx.y * blockDim.y + threadIdx.y;


int M = N/4;

cuComplex w(0.0,0.0), a(0.0,0.0), b(0.0,0.0),c(0.0,0.0),d(0.0,0.0), temp(0.0,0.0),
		  x1(0.0,0.0),x2(0.0,0.0),x3(0.0,0.0),x4(0.0,0.0), j(0.0, 1.0), mj(0.0,-1.0);

	
	for (int stage = 1; stage <=p; stage++) {	
			
		int k=iy*(N/(pow(4.0,stage-1)));
				
			if (n <= M-1 && k <= N-1) {
                        //////////////////it looked like that on a cpu
		//for (int k = 0; k<=N-1; k=k+(N/(pow(4.0,stage-1)))) {
		//		
		//	//for(int n=0; n<=M-1; n++) { 
                       ///////////////////////////////////////////
					x1.r = re_s[n+1+k];
					x1.i = im_s[n+1+k];
					x2.r = re_s[n+(M)+1+k];
					x2.i = im_s[n+(M)+1+k];
					x3.r = re_s[n+(2*M)+1+k];
					x3.i = im_s[n+(2*M)+1+k];
					x4.r = re_s[n+(3*M)+1+k];
					x4.i = im_s[n+(3*M)+1+k];
				
					a = x1+x2+x3+x4;
					b = x1 + mj*x2-x3+j*x4;
					c= x1-x2+x3-x4;
					d = x1+j*x2-x3+mj*x4;
					///////////////////////////////////////////////////////////////////////////////

					/////////  1  /////////////
					w.r = cos(((-2.0*PI)/N)* (0) *(pow(4.0,stage-1)));
					w.i = sin(((-2.0*PI)/N)* (0) *(pow(4.0,stage-1)));
				 temp = w*a;

					re_s[n+1+k] = temp.r;
					im_s[n+1+k] = temp.i;
					/////////  2  /////////////
					w.r = cos(((-2.0*PI)/N)* (n*1) *(pow(4.0,stage-1)));
					w.i = sin(((-2.0*PI)/N)* (n*1) *(pow(4.0,stage-1)));

				temp = w*b;
					re_s[M+n+1+k] = temp.r;
					im_s[M+n+1+k] = temp.i;
					/////////  3 /////////////
					w.r = cos(((-2.0*PI)/N)* (n*2) *(pow(4.0,stage-1)));
					w.i = sin(((-2.0*PI)/N)* (n*2) *(pow(4.0,stage-1)));

				temp = w*c;
					re_s[M*2+n+1+k] = temp.r;
					im_s[M*2+n+1+k] = temp.i;
					/////////  4  /////////////
					w.r = cos(((-2.0*PI)/N)* (n*3) *(pow(4.0,stage-1)));
					w.i = sin(((-2.0*PI)/N)* (n*3) *(pow(4.0,stage-1)));

				temp = w*d;
					re_s[M*3+n+1+k] = temp.r;
					im_s[M*3+n+1+k] = temp.i;
					
					}
					M=M/4;	
				}
	}
 

Linkhero1

Member
poweld said:
An enum is a simple way of creating a series of numbers assigned to values. The point of them is to avoid using "magic numbers". By default, when you define an enum the values begin at 0 and increment by one thereafter. So, A=0, B=1, C=2, etc.

However, they are not like int's in the sense that they do not implicitly convert from any other type (int, double, etc).
Code:
typedef enum Node { A, B, C } Node;
int i = A; // OK
Node j = i; // Won't compile - int does not implicitly convert to Node
Thanks I figured it out eventually :D

I'm having some other trouble though. I want the user to be only able to enter certain characters and exit when they enter other characters. My issue is that even if they enter characters that are allowed it still exits.

Code:
cout << "Enter your first character[A-H]: ";
	cin >> first;
	cout << endl;
	cout << "Enter your second character[A-H]: ";
	cin >> second;
	cout << endl;

	if (first!= 'A'||'B'||'C'||'D'||'E'||'F'||'G'||'H'||'a'||'b'||'c'||'d'||'e'||'f'||'g'||'h')
	{
		cout << "fail ";
		exit(1);
	}

so even if for the first one they enter A it still exits before I can do anything.
 
Hey quick question, can you simply assign pointers to other pointers or is there a special way to do it? For instance can I do

Code:
obj* ptr1 = sdfsdf; // Some assigment
obj* ptr2 = hrtrh;

ptr1 = ptr2;
 

deadbeef

Member
Linkhero1 said:
Thanks I figured it out eventually :D

I'm having some other trouble though. I want the user to be only able to enter certain characters and exit when they enter other characters. My issue is that even if they enter characters that are allowed it still exits.

Code:
cout << "Enter your first character[A-H]: ";
	cin >> first;
	cout << endl;
	cout << "Enter your second character[A-H]: ";
	cin >> second;
	cout << endl;

	if (first!= 'A'||'B'||'C'||'D'||'E'||'F'||'G'||'H'||'a'||'b'||'c'||'d'||'e'||'f'||'g'||'h')
	{
		cout << "fail ";
		exit(1);
	}

so even if for the first one they enter A it still exits before I can do anything.

'B' is an expression that evaluates to a non-zero value, and is interpreted as true. Same goes for 'C', 'D', etc.
 

Linkhero1

Member
I fixed it with this, but idk how to shorten it cuz it looks ugly

Code:
if (_start != 'A')
		if(_start!= 'B')
			if(_start!= 'C')
				if(_start!= 'D')
					if(_start!= 'E')
						if(_start!= 'F')
							if(_start!= 'G')
								if(_start!= 'H')
									if(_start!= 'a')
										if(_start!= 'b')
											if(_start!= 'c')
												if(_start!= 'd')
													if(_start!= 'e')
														if(_start!= 'f')
															if(_start!= 'g')
																if(_start!= 'h')
																{
																cout << "Fail... ";
																exit(1);
																}
 

deadbeef

Member
Linkhero1 said:
I fixed it with this, but idk how to shorten it cuz it looks ugly

Code:
if (_start != 'A')
		if(_start!= 'B')
			if(_start!= 'C')
				if(_start!= 'D')
					if(_start!= 'E')
						if(_start!= 'F')
							if(_start!= 'G')
								if(_start!= 'H')
									if(_start!= 'a')
										if(_start!= 'b')
											if(_start!= 'c')
												if(_start!= 'd')
													if(_start!= 'e')
														if(_start!= 'f')
															if(_start!= 'g')
																if(_start!= 'h')
																{
																cout << "Fail... ";
																exit(1);
																}


You can put them all in one expression like you were doing, you just had an error in it....
 
Status
Not open for further replies.
Top Bottom