Something really weird with C++ exp() function - c++

When tying to implement mySqrt function in C++, I used the exp() function like this:
int mySqrt(int x) {
// For x = 2147395600
cout << exp(0.5*log(x)) << " "; // It prints 46340
return exp(0.5*log(x)); // But returns 46339
}
I tried to google the reason for this behavior but could not find anything. I even tried using double but still the same output.
Any explanation for this?

With this code
#include <iostream>
#include <cmath>
#include <cstdio>
using std::cout;
int mySqrt(int x) {
// For x = 2147395600
cout << exp(0.5*log(x)) << " "; // It prints 46340
return exp(0.5*log(x)); // But returns 46349
}
int main(void) {
std::cout << mySqrt(2147395600) << "\n";
printf("%.30f\n", exp(0.5*log(2147395600)));
return 0;
}
I got output:
46340 46339
46339.999999999978172127157449722290
It seems the value is rounded when passed to cout while truncated when converted to int.

Related

Can't Convert A Float in Array to String

I am trying to create a sine, cosine, tangent, and cotangent table. I want to printf/cout an "INF" instead of huge complicated numbers or interesting symbols when I calculate the cotangent of 0. But it doesn't allow me to do this. I tried every way I can think of, but I couldn't do it.
Can you help me about that?
Code is below:
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <iostream>
#define PI 3.14159265
#include <math.h>
#include <string>
#include <sstream>
using namespace std;
int main()
{
setlocale(LC_ALL, "Turkish");
string diziBaslik[1][5] = {{"AÇI","SİN","COS","TAN","COTAN"}};
string diziBaslikCizgi[1][5] = {{"------","------","------","------","------"}};
float dizi[10][5] = {
{0 ,sin(0*PI/180) ,cos(0*PI/180) ,tan(0*PI/180) ,1/tan(0*PI/180) },
{10,sin(10*PI/180),cos(10*PI/180),tan(10*PI/180),1/tan(10*PI/180)},
{20,sin(20*PI/180),cos(20*PI/180),tan(20*PI/180),1/tan(20*PI/180)},
{30,sin(30*PI/180),cos(30*PI/180),tan(30*PI/180),1/tan(30*PI/180)},
{40,sin(40*PI/180),cos(40*PI/180),tan(40*PI/180),1/tan(40*PI/180)},
{50,sin(50*PI/180),cos(50*PI/180),tan(50*PI/180),1/tan(50*PI/180)},
{60,sin(60*PI/180),cos(60*PI/180),tan(60*PI/180),1/tan(60*PI/180)},
{70,sin(70*PI/180),cos(70*PI/180),tan(70*PI/180),1/tan(70*PI/180)},
{80,sin(80*PI/180),cos(80*PI/180),tan(80*PI/180),1/tan(80*PI/180)},
{90,sin(90*PI/180),cos(90*PI/180),tan(90*PI/180),1/tan(90*PI/180)}
};
cout << diziBaslik[0][0] << "\t";
for(int j=1;j<5;j++){
cout << diziBaslik[0][j] << "\t\t";
}
cout<< endl;
cout << diziBaslikCizgi[0][0] << "\t";
for(int j=1;j<5;j++){
cout << diziBaslikCizgi[0][j] << "\t\t";
}
cout << endl;
for(int i=0;i<10;i++){
for(int j=0;j<5;j++){
if(j==0){
cout << dizi[i][j] << "\xB0\t";
}
else{
printf("%.6f\t", dizi[i][j]);
}
}
cout<<endl;
}
}
There are 2 issues:
Due to low PI precision, tan(90*PI/180) returns a large number and not infinity.
Your system is printing infinity as 1,#INF00. I don't think there's a way to change that.
To work around both issues don't let large values go to printf and instead print your own string if the value is larger than some tolerance value:
if (dizi[i][j] < 1e5) {
printf("%.6f\t", dizi[i][j]);
} else {
printf("INFINITY\t");
}
Also note that setlocale() won't affect cout because it's constructed before. For cout you need to add something like
cout.imbue(std::locale("Turkish"));

How do I check in this code if the number is in integer?

I wrote this code to check the exceptions I learned in a video, and now I tried to make the cube of an integer and if the entered number is not an integer I want the exception to be announced to the user.
#include <iostream>
float cube( float x)
{
char ch;
std::cin.get(ch);
if(ch=='.')
throw "Should be an integrer";
float cube=x*x*x;
return cube;
}
int main ()
{
float x;
std::cout<<" Enter an integrer : ";
std::cin>>x;
float cube_x=cube(x);
std::cout<<"Cube("<<x<<")="<<cube_x<<std::endl;
return 0;
}
You can use boost lexical-cast which is exactly for this purpose. It will throw an exception the conversion fails. Boost is well tested and you can safly use it to do the conversion for you.
This could look like this:
#include <boost/lexical_cast.hpp>
#include <iostream>
int cube(int x)
{
return x*x*x;
}
int main()
{
std::string x;
std::cout << " Enter an integrer : ";
std::cin >> x;
try
{
int y = boost::lexical_cast<int>(x);
int cube_x = cube(y);
std::cout << "Cube(" << x << ")=" << cube_x << std::endl;
}
catch (const boost::bad_lexical_cast &e)
{
std::cerr << e.what() << '\n';
}
return 0;
}
By the way, if your program shall only handle integers, you should also use type int and not float to handle the numbers.
Add the following to your source code:
#include <math.h> /* round, floor, ceil, trunc */
...
if (x == round(x)) {
...
}
Explanation can be found here: C++ Reference

Defining a string in an if statement

Im trying to make a number that is positive (already converted into a string) look like "+number" instead of "number" but i can't define it in an if
#include <iostream>
#include <string>
int main()
{
std::string x3s;
int number = 145;
if (number >= 0)
{
x3s = "+" + number;
}
std::cout << x3s << std::endl;
}
Firstly, there is an I/O manipulator std::showpos.
#include <iostream>
int main()
{
int number = 145;
std::cout << std::showpos << number << std::endl;
}
Secondly, you are using the verb "define" incorrectly.
You can use x3s = std::string("+") + std::to_string(number);

In C++, how do I obtain an output exactly like a calculator?

I use setprecision & fixed, but I want to cut off trailing zeros, how do I do that for cout?
#include <iostream>
#include<iomanip>
int main()
{
double b = 132.7489;
double a = 49.932;
double e = a + b;
std::cout << std::fixed;
std::cout << std::setprecision(20);
std::cout << e;
}
How do I tell the program to automatically cut off the trailing decimal places for the exact answer like a calculator. Sorry this is my first time here. I'm used to Javascript & I've never had a problem with exact math. I've googled everywhere.
This will do it...
#include <iostream>
using namespace std;
int main()
{
float f = 42.43500000f, f2 = 25.004300;
cout << defaultfloat << f << endl;
cout << defaultfloat << f2 << endl;
return 0;
}
defaultfloat is a format flag defined in the std namespace.
If printing is your only concern you could use printf and %g format.
As by default six significant digits are printed ,you could use long enough numeric width like .10.
printf("%.10g",e);
So:
#include <iostream>
#include<cstdio>
int main()
{
double b = 132.7489;
double a = 49.932;
double e = a + b;
printf("%.10g",e);
}

My function does not modify its inputs

I'm trying to learn C++ and have this small beginner question:
why does the standardize function not modify its inputs?
To help with the answers, I have posted an executing code at Coliru
here
and the sources of my program below.
Referring to the code, the question would be: why isn't what's
printed after outside the same as what's printed after inside?
#include <cstdlib>
#include <ctime>
#include <algorithm> // std::copy
#include <iostream>
using namespace std;
void standardize(const int n,const float x[],float ave,float sct){
float acc=0.0f,sum=0.0f;
sum=std::accumulate(x,x+n,0.0f);
ave=sum/(float)n;
std::for_each(x,x+n,[&](const float d){acc+=(d-ave)*(d-ave);});
sct=std::sqrt(acc/(float)(n-1));
std::cout << "inside" << std::endl;
std::cout << ave << std::endl;
std::cout << sct << std::endl;
return;
}
int main(){
const int n=1024;
float a2[n];
float part0=0.0f,part1=0.0f;
std::srand(std::time(0));
for(int i=0;i<n;i++) a2[i]=std::rand()/(float)RAND_MAX;
standardize(n,a2,part0,part1);
std::cout << "outside" << std::endl;
std::cout << part0 << std::endl;
std::cout << part1 << std::endl;
}
You are passing ave and sct by values. Your standardize method modifies copies of those arguments, letting unchanged the original ones declared in main()
Consider passing them by reference:
void standardize(const int n,const float x[],float& ave,float& sct)