Assert in C Language - assert

So I tried write a code to convert kmph to m/s
And wanted to validate using Assert.
Here is the piece of code I wrote.
The value is correct when tried comparing with print statements but assert gives an error
#include <stdio.h>
#include <assert.h>
float convert(float num);
int main()
{
float kmph;
printf("Enter Velocity in Kmph\n");
scanf("%f", &kmph);
printf("Velocity in m/s is %f\n", convert(kmph));
assert(convert(1) == 0.277778);
assert(convert(18) == 5.0);
return 0;
}
float convert(float num)
{
float mps;
mps = num * 0.277778;
return mps;
}
error description:
Enter Velocity in Kmph
1
Velocity in m/s is 0.277778
a.out: program4.c:14: main: Assertion `convert(1) == 0.277778' failed.
Aborted (core dumped)

Related

Segmentation fault, while running a Monte-Carlo-random-walk simulation in c++

I am trying to simulate a random walk of 2000 particles, while the one boundary has the ability to make particles bound on that and merely perform a biased step.
There are of course probabilities for binding unbinding etc...
Below I have the whole code.
However I get segfault error.
I put some print statements in the code to see where the issue lies. But nothing. What I found strange though, is that although seed is fixed, the length of the output statement determined the loop, where code crushed.
I am totally inexperienced in these issues, so if you have any idea on what I could do, would be appreciated.
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <fstream>
#include <string>
using namespace std;
const int pi=6;
const int epsilon=10;
const int X=3000;
const int Y=30; //length
const int time_steps=100000;
const int N=2000; // number of molecules
int kinesins[N][3]={0};//[X,Y,bound or not]
int grid[X][Y][2]={0};
void place_kinesins(){
for (int i=0; i<N;i++){
int x= rand()%X;
int y= (rand()%(Y-2))+2;
if (grid[x][y][0]==0){
kinesins[i][0]=x;
kinesins[i][1]=y;
kinesins[i][2]=0;
grid[x][y][0]=1;
}else{i--;}
}
}
void create_boundaries(){
for(int i=0;i<Y;i++){
grid[0][i][1]=-1;
grid[X-1][i][1]=-3;
}
for (int i=0; i<X; i++){
grid[i][Y-1][1]=-2;
}
}
void create_filament(){ //in order to create binding affinity.
for(int i=0; i<X;i++){
grid[i][1][1]=pi;
}
}
void step(int kinesin, int x_step, int y_step){
int x=kinesins[kinesin][0];
int y=kinesins[kinesin][1];
int x_end=x+x_step;
int y_end=y+y_step;
if (grid[x_end][y_end][0]==0){
grid[x][y][0]=0;
kinesins[kinesin][0]=x_end;
kinesins[kinesin][1]=y_end;
grid[x_end][y_end][0]=1;
}
}
void bound(int kinesin){
int roll=rand()%10000 ;
if (roll<epsilon){
kinesins[kinesin][2]=0;
step(kinesin,0,1);
}else{
if (roll%63==0){ //controls the binding rate speed
step(kinesin, 1,0);
};
}
}
void unbound(int kinesin){
cout<<"1";
int x= kinesins[kinesin][0];
int y= kinesins[kinesin][1];
int type= grid[x][y][1];
switch(type){
case 0:{
cout<<"2";
int roll=rand()%4;
switch(roll){
case 0:
step(kinesin,-1,0);
break;
case 1:
step(kinesin,1,0);
break;
case 2:
step(kinesin,0,1);
break;
case 3:
step(kinesin,0,-1);
break;
}
break;
}
case -1:
step(kinesin,1,0);
break;
case -2:
step(kinesin,0,-1);
break;
case -3:
step(kinesin,-1,0);
break;
default:
int roll=rand()%10000;
if(roll<grid[x][y][1]){kinesins[kinesin][2]=1;}
else{ if(roll%2==0){step(kinesin,0,1);}}
}
}
void kinesin_move(int kinesin){
cout<<" "<<kinesins[kinesin][0]<<kinesins[kinesin][1];
if (kinesins[kinesin][2]==0){
unbound(kinesin);
}else{
cout<<"3";
bound(kinesin);
}
}
void simulation(){
for(int j=7000; j<time_steps;j++){
cout<<endl<< j<<" "<<endl;
for (int kin=0; kin<N; kin++){
cout<<kin;
kinesin_move(kin);
cout<<"E " ;
}
}
}
void programm(){
srand(1);
create_boundaries();
create_filament();
cout<<"Filament done"<<endl;
place_kinesins();
cout<<"Kines placed"<<endl;
simulation();
}
int main(){
programm();
return 0;
}
Problem:
In the function step you're accessing the array grid out of its bonds, which produces Undefined Behaviour and the segmentation fault.
This can be proven adding an assert before if (grid[x_end][y_end][0]==0):
if(!(x_end < X && x_end >= 0))
std::cerr << x_end << std::endl;
assert(x_end < X && x_end >= 0);
if (grid[x_end][y_end][0]==0){
grid[x][y][0]=0;
kinesins[kinesin][0]=x_end;
kinesins[kinesin][1]=y_end;
grid[x_end][y_end][0]=1;
}
Output:
3000
Assertion failed: x_end < X && x_end >= 0 main.cpp line 57
This application has requested the Runtime to terminate it in an unusual way.
Solution:
You will have to check the arguments for step won't make it go out of bonds before each call.
Additional information:
using namespace std; is considered a bad practice (More info here).
rand is not uniformly distributed. You may want use the <random> library instead (More info here).
Global variables are bad (More info here).
You may want to use std::array instead of raw, C-style arrays.

3D array picks up unrealistic values while compiling and not the ones already set

The following code is the first part to simulate molecular dynamics in 3D lattices. I'm having issues with the 3D array picking up garbage values.Not at all locations, but some because of which the entire result goes wrong.I've also noticed that the error occurs when the dimension of my array is 5*5*5 onwards(for this particular simulation the least length of the cube's side should be 3). Also the code takes suspiciously longer time to complete than expected.Please comment on that issue as well if possible. And please ignore the obvious comments like what each function does, I'd done it so that I don't forget. Thanks in advance.
#include <iostream>
#include <cstdlib> // has rand(),srand().
#include <ctime> // has time.
#include <fstream> // enables file handling.
#include <math.h>
using namespace std;
float rand_gen(); //full function written after main().
//int pbc(int,int,int);
int main()
{
srand((int)time(0)); //sets time as the seed for the random no. generation.
int dim=5;
int i,j,k,iup,idown,jup,jdown,kup,kdown;//indices
float x;
int l[dim][dim][dim];
float M=0.0,E=0.0;
for(i=1;i<=dim;i++)
{
for(j=1;j<=dim;j++)
{
for(k=1;k<=dim;k++)
{
x=rand_gen();
if(x<=0.5)
{
l[i][j][k]=-1; //sets the value in that particular location.
}
else
{
l[i][j][k]=1; //sets the value in that particular location.
}
M=M+l[i][j][k];
}
}
}
cout<<"Total magnetisation= "<<M<<endl;
for(i=1;i<=dim;i++)
{
for(j=1;j<=dim;j++)
{
for(k=1;k<=dim;k++)
{
if(i==1)iup=dim; //*********************************
else iup=i-1;
if(i==dim)idown=1;
else idown=i+1;
if(j==1)jup=dim;
else jup=j-1; //periodic boundary condition.
if(j==dim)jdown=1;
else jdown=j+1;
if(k==1)kup=dim;
else kup=k-1;
if(k==dim)kdown=1;
else kdown=k+1; // ends here//
E=E-(l[i][j][k]*(l[iup][j][k]+l[idown][j][k]+l[i][jup][k]+l[i][jdown][k]+l[i][j][kup]+l[i][j][kdown]))/2.0;
}
}
}
cout<<"Average E= "<<E/(dim*dim*dim)<<endl;
//cout<<"Testing: "<<l[5][4][3]<<" "<<l[5][4][3]<<endl;;
//**************************ALL FINE TILL HERE IT SEEMS****************************************************//
int n=100; //Number of iterations.
int no,site;
int ri,rj,rk,riup,ridown,rjup,rjdown,rkup,rkdown;
float eng=0.0,mag=M;float E_check=0.0;
float E_b4,E_aft,E_diff;
float T=4.2;
float a;
ofstream file ("Energy_check"); //file created to write the results into.
//ofstream file1 ("ENERGY1.txt");
for(no=1;no<=n;no++)
{
for(site=1;site<=(dim*dim*dim);site++)
{
float v1=rand_gen();
float v2=rand_gen();
float v3=rand_gen();
ri= int(v1*dim)+1;
rj= int(v2*dim)+1;
rk= int(v3*dim)+1;
//if((ri>=1&&ri<=dim)&&(rj>=1&&rj<=dim)&&(rk>=1&&rk<=dim))
{if(ri==1)riup=dim; //periodic boundary condition like above
else riup=ri-1;
if(ri==dim)ridown=1;
else ridown=ri+1;
if(rj==1)rjup=dim;
else rjup=rj-1;
if(rj==dim)rjdown=1;
else rjdown=rj+1;
if(rk==1)rkup=dim;
else rkup=rk-1;
if(rk==dim)rkdown=1;
else rkdown=rk+1; // ends here
}
E_b4=-(l[ri][rj][rk]*(l[riup][rj][rk]+l[ridown][rj][rk]+l[ri][rjup][rk]+l[ri][rjdown][rk]+l[ri][rj][rkup]+l[ri][rj][rkdown]))/2.0;
E_aft=-(E_b4);
E_diff=-2.0*(E_b4);
E_check=E_check+E_b4;
if(E_diff<0)
{
l[ri][rj][rk]=-l[ri][rj][rk];
eng=eng+E_diff;
mag=mag-2*l[ri][rj][rk];
}
else
{
a=rand_gen();
if(a<pow(exp(1.0),-E_diff/T))
{
l[ri][rj][rk]=-l[ri][rj][rk];
eng=eng+E_diff;
mag=mag-2*l[i][j][k];
}
}
if(file.is_open())
{ // THE FOLLOWING CODE IS SUPPOSED TO SHOW THE VALUES OF THE ARRAY CORRESPONDING TO ITS INDICES. bUT IM GETTING GARBAGE VALUES WHEN I RUN THIS.
file<<no<<" "<<ri<<rj<<rk<<" "<<l[ri][rj][rk]<<" "<<riup<<rj<<rk<<" "<<l[riup][rj][rk]<<" "<<ridown<<rj<<rk<<" "<<l[ridown][rj][rk]<<" "<<ri<<rjup<<rk<<" "<<l[ri][rjup][rk]<<" "<<ri<<rjdown<<rk<<" "<<l[ri][rjdown][rk]<<" "<<ri<<rj<<rkup<<" "<<l[ri][rj][rkup]<<" "<<ri<<rj<<rkdown<<" "<<l[ri][rj][rkdown]<<" "<<E_b4<<" "<<E_check<<endl;
}
}
E=(E+eng)/(dim*dim*dim);
/*if(file1.is_open())
{
file1<<no<<"\t"<<E<<endl;
}*/
}
file.close();
//file1.close();
cout<<"E_check_avg= "<<E_check/(dim*dim*dim)<<endl;
return 0;
}
float rand_gen() //function to generate random number.
{
return (static_cast <float> (rand()) / static_cast <float> (RAND_MAX));// random no. generated.
}

How to prevent overflow when using usual math functions exp() log()?

All is in the title. How to check a possible overflow when using the two functions exp() and log()?
#include <errno.h>
When an oferflow occurs, then errno is set to ERANGE.
Next time, do your homework before asking.
Googling: "c++ exp" returned this as the first result http://www.cplusplus.com/reference/cmath/exp/
In the middle of the page, there is EXACTLY what you're looking for.
To expand the answer of #TheOtherGuy, you can cancel the operation if overflow occurs.
#include <stdio.h>
#include <math.h>
#include <errno.h>
int main(void)
{
double param, result;
errno = 0;
param = 1e3;
result = exp (param);
if (errno == ERANGE) {
printf("exp(%f) overflows\n", param);
result = param;
}
printf ("The exponential value of %f is %f.\n", param, result );
return 0;
}
The best way to check for overflow beforehand is to do so intelligently on a case-by-case basis.
Using your knowledge of logarithms and exponents, you should be able to identify potential overflows using properties like INT_MAX: examine these C++ Limitations
I threw a rough sample c++ execution together, assuming you know beforehand what limits you are attempting to follow.
#include <iostream>
// nTh root calculator
bool is_exp_overflow(int input_val, int exponent)
{
my_max = pow(INT_MAX, (1/exponent);
if (input_val > my_max)
{
return true;
}
else
return false;
}
void runExp(int my_input, int my_exp)
{
// Do maths
}
int main()
{
int my_input = 0;
int my_exp = 0;
std::cout << "Enter test value\n";
std::cin >> my_input;
std::cout << "Enter test exponent\n";
std::cin >> my_exp;
bool exp_unsafe = 1;
exp_unsafe = is_exp_overflow(my_input, my_exp);
if (!exp_unsafe)
runExp(my_input, my_exp);
else
std::cout << "Code is unsafe\n";
return 0;
}
If you're looking to catch the errors post mortem, examine errno in range.
For the exp() handling:
Just compare against a variable which you assign to log(FLT_MAX). FLT_MAX is biggest float.
You can do this before calculating an exp(). Because log() is inverse of exp() .
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
float a=1E+37f; // an example of maximum finite representable floating-point number.
//max value can change with platform so,
//either use definitions or use a function you wrote
// a= getMaxFloat(); or a=FLT_MAX
float b=log(a); // limit of float to give in exp();
float c=3242325445.0f; // test variable
cout << "Hello world!" << endl;
if(c>b){cout<<"you should not take exp of "<<c<<endl;}else{cout<<"go on"<<endl;}
return 0;
}
For the log() handling:
1)You cannot everflow log(x) before overflowing x. (for the upper bound)
2)Float's/Double's (x) precision is not enough to overflow to negative-infinity for log(x).
3)Make sure x is bigger than zero.
Better than prevent, you can catch the exception:
try {
z=exp(n);
} catch (...) {
puts("Can't calcute exp...");
}

mpi determinant, CODE: 11 segmentation fault

I'm new to mpi and I want to write a program in C++ that calculates the determinant of a matrix and in the beginning of trying to write it I get this error when trying to compile with mpi compiler.
#include "mpi.h"
#include <iostream>
#include <stdio.h>
#include "/usr/include/malloc.h"
using namespace std;
int matrix[3][3] = {{1,2,3},
{4,5,6},
{7,8,9}};
//**************
int** MakeMatrix (int** oldMatrix,int I,int J,int m,int n)
{
int** newMatrix = (int**)malloc(sizeof(int*)*J);
for(int i=0;i<J;i++)
{
newMatrix[i] = (int*)malloc(sizeof(int)*I);
}
for(int i=0;i<I-1;i++)
for(int j=0;j<J-1;j++)
if(i>=m)
if(j>=n)
{
newMatrix[i][j]=oldMatrix[i+1][j+1];
}
else
{
newMatrix[i][j]=oldMatrix[i+1][j];
}
else
{
newMatrix[i][j]=oldMatrix[i][j];
}
return newMatrix;
}
///////////////////////
int determinan (int** lmatrix,int I,int J)
{
if(I*J==1)
{
return lmatrix[I-1][J-1];
}
int minus = -1;
int sum = 0;
for(int j=0;j<J-1;j++)
{
for(int k=1;k<I+j+1;k++,minus*=minus);
sum += minus*lmatrix[0][j]*determinan(MakeMatrix(lmatrix,I,J,0,j),I-1,J-1);
}
return sum;
}
///*************
int main(int argc,char **argv)
{
//MPI_Init(&argc,&argv);
cout<<determinan((int**)matrix,3,3)<<'\n';
//MPI_Finalize();
return 0;
}
and here is the error message :
===================================================================================
= BAD TERMINATION OF ONE OF YOUR APPLICATION PROCESSES
= EXIT CODE: 11
= CLEANING UP REMAINING PROCESSES
= YOU CAN IGNORE THE BELOW CLEANUP MESSAGES
===================================================================================
YOUR APPLICATION TERMINATED WITH THE EXIT STRING: Segmentation fault (signal 11)
This typically refers to a problem with your application.
Please see the FAQ page for debugging suggestions
I am sure there are multiple problems. The immediate one is the type cast in:
cout<<determinan((int**)matrix,3,3)<<'\n';
^^^^^^^
This isn't a valid cast since matrix isn't an array of pointers.

Cannot compute equation, always gives zero

Did i miss something? The variable percentage_ always equals 0. I've checked nTimes and winnings, they give the correct values as what is being input. Even when I test out a simple equation like, percentage_=1+1, percentage_ will give 0. Can someone help?
#pragma once
#include <iostream>
#include <string>
#include <cstdlib>
#include <iomanip>
using namespace std;
class GuessMachine
{
private:
int nTimes;
int winnings;
string nM[6];
public:
GuessMachine();
void displayPrizes();
void displayMenu();
int getInput();
void checkNumber();
void checkPrize();
};
void GuessMachine::checkPrize()
{
MagicNumber mn;
int prize_=mn.generateNumber();
float percentage_;
percentage_ = float (winnings/nTimes*100); //<--On this line percentage is always 0 no matter what winnings and nTimes are
cout<<"Percentage is "<<percentage_<<endl;
if(percentage_ >= 50)
{
cout<<"You have scored "<<percentage_<<"% and won "<<nM[prize_];
}
else
{
cout<<"You have scored "<<percentage_<<"%. You lose!!";
}
cin.ignore();
cin.ignore();
}
Try
float (winnings) /nTimes*100
instead.
Your version still converts an int - 0 to a float.
If one operand to / is a float, it will work.
Change
percentage_ = float (winnings/nTimes*100);
to
percentage_ = (float(winnings))/nTimes*100;
since you need to change 1 number to float for the division to work on floats.