I have this exercise where i don't understand the method float set(void).So, at first A::v is initialized as a unknown number(1234 for example) but after A::v = v + 1.0.
The result should be A::v= 1234 + 1.0.
It isn't,instead it is A::v=1.
#include <iostream>
using namespace std;
class A {
public:
float v;
float set(void) {
A::v = v + 1.0;
return A::v;
}
};
int main() {
A a;
cout<<a.set()<<endl;
return 0;
}
The answer to your question why the value is always 1:
well, it isn't. It depends on whatever is left there in memory. You have seen a few examples where the uninitialized float value is so small that adding 1.0 to it yields something close to 1.0
But that certainly may not always be the case!
Initialize the variable to 0.
Some further reading:
What Every Computer Scientist Should Know About Floating-Point Arithmetic
You just not initialize value inside class.
When you allocate space on stack, values are random junk.
#include <iostream>
using namespace std;
class A {
public:
float v = 1234.0; //You must initialize it with 1234 if you want result 1235
float set(void) {
/*A::v*/ v = v + 1.0;
return A::v;
}
};
int main() {
A a; //Initializing space on stack, uninitialized values are always, 0x00, 0xcd or trash from other functions.
cout<<a.set()<<endl;
return 0;
}
Related
#include <iostream>
using namespace std;
class idk{
public:
int x;
int y;
};
void obj(idk* obj[]){
obj[0]-> x = 1000;
obj[0]-> y = 30;
}
int main(){
idk *z[5];
obj(z);
cout << z[0]->x;
return 0;
}
I am just trying out how to use pointers. The problem is when I set my array 'z' size to 5 or any number it doesn't do anything, however when I make it 10 it then prints out the correct output. Ive tried pasting the code into an online compiler and it also plays up there but with other numbers. Is my code wrong or missing some things?
In this
idk *z[5];
you declare 5 idk pointers. These are only pointers that you can assign to point at idks, but you have not created any actual idks. When you later dereference the first pointer you get undefined behavior since it's not actually pointing at an idk:
void obj(idk* obj[]){
obj[0]-> x = 1000; // BOOM
Making the array of pointers actually point at idk instances can be made in many different ways. Here's one:
#include <iostream>
class idk{
public:
int x;
int y;
};
void obj(idk* obj[]){
obj[0]-> x = 1000;
obj[0]-> y = 30;
}
int main(){
idk instances[5];
idk *z[5]{
&instances[0],
&instances[1],
&instances[2],
&instances[3],
&instances[4],
}; // now all five point at one idk instance each
obj(z);
std::cout << z[0]->x;
}
Another option would be to skip the pointer array completely:
#include <iostream>
class idk {
public:
int x;
int y;
};
void obj(idk obj[]) {
obj[0].x = 1000;
obj[0].y = 30;
}
int main() {
idk z[5];
obj(z);
std::cout << z[0].x;
}
Previously I asked how to make a random number generator in C++ here, and with other people's help I got it right.
Now, I'm trying to return the result as vectors instead of a series of numbers, but it doesn't seem working right. I know that void is not meant to return anything, but using double instead of void didn't work either..
To give more details, I'm trying to return two containers named x_coord and y_coord that contain all the result from x_coord.push_back(oldRoot) and y_coord.push_back(newRoot). I'm doing this because I need them for later use. What is the best way to do this? Thank you for help in advance.
#include <iostream>
#include <vector>
using namespace std;
// Generate random x and y coordinates for 128 particles
class Random {
public:
double oldRoot;
double newRoot;
int iteNum;
Random(double aOldRoot, double aNewRoot, int aIteNum) {
oldRoot = aOldRoot;
newRoot = aNewRoot;
iteNum = aIteNum;
}
void generate() {
vector<double> x_coord;
vector<double> y_coord;
int count = 0;
while (count <= iteNum) {
double totalRoot = oldRoot + newRoot;
if (totalRoot > 1.0) {
oldRoot = newRoot;
newRoot = totalRoot - 1.0;
x_coord.push_back(oldRoot);
y_coord.push_back(newRoot);
}
else {
oldRoot = newRoot;
newRoot = totalRoot;
x_coord.push_back(oldRoot);
y_coord.push_back(newRoot);
}
count += 1;
}
return x_coord, y_coord;
}
};
int main() {
Random random10(0.1412, 0.2343, 16);
random10.generate();
return 0;
}
A simple option would be to return the 2 vectors as a std::pair, like this:
std::pair<std::vector<double>, std::vector<double>> generate() {
// fill up the vectors
return {x_coord, y_coord};
}
However, I would suggest storing the x and y co-ordinates together in a data structure, like this:
std::vector<std::pair<double, double>> xy_coord;
since the x and y co-ordinates should probably be pairwise connected.
You can insert pairs of randomly generated numbers like this:
xy_coord.push_back({oldRoot, newRoot});
The error appeared because you defined the function generate() has returning type is void while you are return x_coord, y_coord;
To fix it, you must have returning type like std::pair<vector<double>, vector<double>> because your x_coord and y_coord are vector<double> and you are returning them at the same time as a tuple.
Basically, you could do something like:
std::pair<vector<double>, vector<double>> generate() {
vector<double> x_coord;
vector<double> y_coord;
//Put your code here...
return {x_coord, y_coord};
}
I just discovered some dodgy problems when i was interleaving some floats. I've simplified the issue down and tried some tests
#include <iostream>
#include <vector>
std::vector<float> v; // global instance
union{ // shared memory space
float f; // to store data in interleaved float array
unsigned int argb; // int color value
}color; // global instance
int main(){
std::cout<<std::hex; // print hexadecimal
color.argb=0xff810000; // NEED A==ff AND R>80 (idk why)
std::cout<<color.argb<<std::endl; // NEED TO PRINT (i really dk why)
v.insert(v.end(),{color.f,0.0f,0.0f}); // color, x, y... (need the x, y too. heh..)
color.f=v[0]; // read float back (so we can see argb data)
std::cout<<color.argb<<std::endl; // ffc10000 (WRONG!)
}
the program prints
ff810000
ffc10000
If someone can show me i'm just being dumb somewhere that'd be great.
update: turned off optimizations
#include <iostream>
union FLOATINT{float f; unsigned int i;};
int main(){
std::cout<<std::hex; // print in hex
FLOATINT a;
a.i = 0xff810000; // store int
std::cout<<a.i<<std::endl; // ff810000
FLOATINT b;
b.f = a.f; // store float
std::cout<<b.i<<std::endl; // ffc10000
}
or
#include <iostream>
int main(){
std::cout<<std::hex; // print in hex
unsigned int i = 0xff810000; // store int
std::cout<<i<<std::endl; // ff810000
float f = *(float*)&i; // store float from int memory
unsigned int i2 = *(unsigned int*)&f; // store int from float memory
std::cout<<i2<<std::endl; // ffc10000
}
solution:
#include <iostream>
int main(){
std::cout<<std::hex;
unsigned int i=0xff810000;
std::cout<<i<<std::endl; // ff810000
float f; memcpy(&f, &i, 4);
unsigned int i2; memcpy(&i2, &f, 4);
std::cout<<i2<<std::endl; // ff810000
}
The behavior you're seeing is well defined IEEE floating point math.
The value you're storing in argb, when interpreted as a float will be a SNaN (Signaling NaN). When this SNaN value is loaded into a floating point register, it will be converted to a QNaN (Quiet NaN) by setting the most significant fraction bit to a 1 (and will raise an exception if floating point exceptions are unmasked).
This load will change your value to from ff810000 to ffc10000.
Writing to the int and then reading from the float in the union causes UB. If you want to create a vector of mixed value types, make a struct to hold them. Also, don't use unsigned int when you need exactly 32 bits. Use uint32_t.
#include <iostream>
#include <vector>
struct gldata {
uint32_t argb;
float x;
float y;
};
std::vector<gldata> v;
int main() {
std::cout << std::hex; // print hexadecimal
v.emplace_back(gldata{0xff810000, 0.0f, 0.0f});
std::cout << v[0].argb << "\n"; // 0xff810000
}
This was an interview question:
Say there is a class having only an int member. You do not know how many bytes the int will occupy. And you cannot view the class implementation (say it's an API). But you can create an object of it. How would you find the size needed for int without using sizeof.
He wouldn't accept using bitset, either.
Can you please suggest the most efficient way to find this out?
The following program demonstrates a valid technique to compute the size of an object.
#include <iostream>
struct Foo
{
int f;
};
int main()
{
// Create an object of the class.
Foo foo;
// Create a pointer to it.
Foo* p1 = &foo;
// Create another pointer, offset by 1 object from p1
// It is legal to compute (p1+1) but it is not legal
// to dereference (p1+1)
Foo* p2 = p1+1;
// Cast both pointers to char*.
char* cp1 = reinterpret_cast<char*>(p1);
char* cp2 = reinterpret_cast<char*>(p2);
// Compute the size of the object.
size_t size = (cp2-cp1);
std::cout << "Size of Foo: " << size << std::endl;
}
Using pointer algebra:
#include <iostream>
class A
{
int a;
};
int main() {
A a1;
A * n1 = &a1;
A * n2 = n1+1;
std::cout << int((char *)n2 - (char *)n1) << std::endl;
return 0;
}
Yet another alternative without using pointers. You can use it if in the next interview they also forbid pointers. Your comment "The interviewer was leading me to think on lines of overflow and underflow" might also be pointing at this method or similar.
#include <iostream>
int main() {
unsigned int x = 0, numOfBits = 0;
for(x--; x; x /= 2) numOfBits++;
std::cout << "number of bits in an int is: " << numOfBits;
return 0;
}
It gets the maximum value of an unsigned int (decrementing zero in unsigned mode) then subsequently divides by 2 until it reaches zero. To get the number of bytes, divide by CHAR_BIT.
Pointer arithmetic can be used without actually creating any objects:
class c {
int member;
};
c *ptr = 0;
++ptr;
int size = reinterpret_cast<int>(ptr);
Alternatively:
int size = reinterpret_cast<int>( static_cast<c*>(0) + 1 );
I have tried to obtain 2 pointers from a function and print it in main. the vague thing is one pointer seems to have recovered its values, while the other hasn't. And both the pointers, have the correct value inside the calling function, just before returning as well. Please tell me if you can identify any programmatic error that is preventing me from getting the right answer.
#include<iostream>
#include<fstream>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
using namespace std;
double* readctrls()
{
fstream inputs;
inputs.open("input_coods.txt");
int nol = 0,i = 0;
string line,temp,subtemptrans,subtemprots;
while(getline(inputs,line))
{
++nol;
}
// cout<<nol<<endl;
inputs.close();
inputs.open("input_coods.txt");
string *lines = new (nothrow) string[nol];
double* trans = new double[nol];
double* rots = new double[nol];
trans[0] =float(nol);
for(int i = 0; i<nol ; i++)
{
getline(inputs,lines[i]);
// cout<<lines[i]<<endl;
temp = lines[i];
// cout<<temp<<endl;
for(int j = 0; j<temp.length() ; j++)
{
if(temp.at(j) == ' ')
{
subtemptrans = temp.substr(0,j);
subtemprots = temp.substr(j+1,temp.length()-j);
// cout<<subtemprots<<endl;
*(trans+i+1) = ::atof(subtemptrans.c_str());
*(rots+i) = float(atoi(subtemprots.c_str()));
// cout<<rots[i]<<endl;
}
}
}
inputs.close();
// cout<<rots[2]<<endl;
return(rots,trans);
}
int main()
{
double *trans,*rots;
(rots,trans) = readctrls();
// cout<<sizeof(trans)<<endl;
for(int i=0;i<trans[0];i++)
{
cout<<*(trans+i)<<endl;
cout<<*(rots+i)<<endl;
}
}
The value of Trans is written fine in the memory and is perfectly retained from the main(). But the rots is giving garbage values of the order (e^-42). Please help me here.
C++ is neither Python nor Lua.
You can't return multiple values from a function.
return rots, trans;
This is the comma operator - evaluates its operands and yields the last (rightmost) one.
(rots, trans) = readctrls();
Likewise, this assigns to trans only, rots will be uninitialized.
Solution: you can either return a struct containing the two pointers, or pass them by reference, or whatever...
struct Foo {
double *rots;
double *trans;
};
Foo readctrls()
{
// ...
Foo r;
r.rots = rots;
r.trans = trans;
return r;
}
or:
void readctrls(double *&r, double *&t)
{
// ...
r = rots;
t = trans;
}
Other remarks:
Don't use raw arrays. std::vector<T> is generally preferred over T * in C++.
It's super wasteful to read the entire file just in order to count the lines, then read it once again to actually parse its contents. If you used an std::vector<double>, you could just vector.push_back(some_double); as you go along the lines, so you wouldn't have to walk through the file twice (you know, I/O is expensive, especially if the file is large).
You never delete the pointers that you allocate using new - here your program leaks memory.