Remove numbers after decimal point in c++ (without floor() function) - c++

How would i replicate the code below but without using the floor() function? I need to do this because i'm in a postion that i cannot use the floor() function
double quickExampleee = 3.1459038585;
std::cout << std::floor(quickExamplee * 100.) / 100. << std::endl;
I've searched for answers all around and haven't been able to find anything? Anyways thanks for your time,

What about using std::setprecision if you don't like to cast the numbers to int's, like
std::cout << std::setprecision(0) << quickExamplee << std::endl;
so to print out 3.14 you simply set precision to 2, like
std::cout << std::setprecision(2) << quickExamplee << std::endl;

You could do static_cast<int>(quickExampleee * 100.) as long as the double is greater than 0.

int myFloorForWhateverReason(double x) {
if (x > 0.0)
return (int)x;
else
return (int)(x - 0.5);
}
double quickExampleee = 3.1459038585;
std::cout << myFloorForWhateverReason(quickExamplee * 100.) / 100. << std::endl;

Related

Double precision issues when converting it to a large integer

Precision is the number of digits in a number. Scale is the number of
digits to the right of the decimal point in a number. For example, the
number 123.45 has a precision of 5 and a scale of 2.
I need to convert a double with a maximum scale of 7(i.e. it may have 7 digits after the decimal point) to a __int128. However, given a number, I don't know in advance, the actual scale the number has.
#include <iostream>
#include "json.hpp"
using json = nlohmann::json;
#include <string>
static std::ostream& operator<<(std::ostream& o, const __int128& x) {
if (x == std::numeric_limits<__int128>::min()) return o << "-170141183460469231731687303715884105728";
if (x < 0) return o << "-" << -x;
if (x < 10) return o << (char)(x + '0');
return o << x / 10 << (char)(x % 10 + '0');
}
int main()
{
std::string str = R"({"time": [0.143]})";
std::cout << "input: " << str << std::endl;
json j = json::parse(str);
std::cout << "output: " << j.dump(4) << std::endl;
double d = j["time"][0].get<double>();
__int128_t d_128_bad = d * 10000000;
__int128_t d_128_good = __int128(d * 1000) * 10000;
std::cout << std::setprecision(16) << std::defaultfloat << d << std::endl;
std::cout << "d_128_bad: " << d_128_bad << std::endl;
std::cout << "d_128_good: " << d_128_good << std::endl;
}
Output:
input: {"time": [0.143]}
output: {
"time": [
0.143
]
}
0.143
d_128_bad: 1429999
d_128_good: 1430000
As you can see, the converted double is not the expected 1430000 instead it is 1429999. I know the reason is that a float point number can not be represented exactly. The problem can be solved if I know the number of digit after the decimal point.
For example,
I can instead use __int128_t(d * 1000) * 10000. However, I don't know the scale of a given number which might have a maximum of scale 7.
Question> Is there a possible solution for this? Also, I need to do this conversion very fast.
I'm not familiar with this library, but it does appear to have a mechanism to get a json object's string representation (dump()). I would suggest you parse that into your value rather than going through the double intermediate representation, as in that case you will know the scale of the value as it was written.

Returning incorrect values of floor function in C++ [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 2 years ago.
The code:
cout << log(25.0/9.0)/log(5.0/3.0) << endl << floor(log(25.0/9.0)/log(5.0/3.0));
results:
2
1
Why does C++ considers floor(2) = 1?
What I tried:
When saving the fraction in a float it returns the correct value:
float a = log(25.0/9.0)/log(5.0/3.0);
cout << a << endl << floor(a);
results:
2
2
Set your precision. floor is correct;
std::cout << std::fixed << std::setprecision(20) << std::endl << log(25.0 / 9.0) / log(5.0 / 3.0) << std::endl << floor(log(25.0 / 9.0) / log(5.0 / 3.0)) << std::endl;
float a = log(25.0 / 9.0) / log(5.0 / 3.0);
std::cout << std::fixed << std::setprecision(20) << std::endl<< a << std::endl << floor(a) << std::endl;
double b = log(25.0 / 9.0) / log(5.0 / 3.0);
std::cout << std::fixed << std::setprecision(20) << std::endl << b << std::endl << floor(b) << std::endl;
this produces
1.99999999999999955591
1.00000000000000000000
2.00000000000000000000
2.00000000000000000000
1.99999999999999955591
1.00000000000000000000
I complied and checked the whole code and let me share my analysis with you.
If you do log(25.0/9.0)/log(5.0/3.0) division directly the compiler treats it as double and the double division result is equal to 1.9999999999999996. If it is rounded it will become 2 and if floor operation is done on this it will become 1 as floor() function in C++ returns the largest possible integer value which is less than or equal to the given argument. In this example it will always return 1.
If the division log(25.0/9.0)/log(5.0/3.0) is treated as float it will result in 2.0000000039152304 (treating each operand as float and storing result in double for understanding) hence in this case round and floor operation will have same result that is 2.
Good Luck
I had same problem two days ago when I was solving a problem on Codeforces. I was using floor function and its returning its different value. I went to google and found some answers here on stackoverflow telling me to use cout << std::fixed, but this function will return float values with decimal point which is not accepted on Codeforces. After a little bit of google search I found this following formula to calculate floor value of a/b.
floor = (a/b) + ((a%b)!=0)
Hope this helps :)

two equal calculations not returning the same result

I got two different .cpp files with two equal calculations.. But they don't return the same results?
A code
double theta = (double)maxLoc.y/angleBins*CV_PI;
std::cout << theta << " " << abs(sin(theta)) << std::endl;
A result
1.53589 0.999391
B code
double theta = (double)maxLoc.y / angleBins * CV_PI;
std::cout << theta << " " << abs(sin(theta)) << std::endl;
B result
1.53589 0
You're probably calling the abs function from C in the second code snippet which takes an int as parameter. Using std::abs in both code snippets (and the correct header #include<cmath>) will fix the problem.

Double: using the actual number of decimal places

I'm creating a calculator program, but I don't know how to set the precision of the decimal places of the calculated answer so that the actual number of decimal places is displayed.
Examples:
-If the answer is 6, it would display 6, not 6.0000000
-if the answer is 8.23, it would display 8.23, not 8.23000000
etc.
How would I set the precision as such?
In C++, use the method precision to set the number of needed placeholders, like:
double f = 3.14159;
std::cout.unsetf ( std::ios::floatfield ); // floatfield not set
std::cout.precision(5); //will output 5 digits after point
std::cout << f << '\n';
std::cout.precision(10); //will output 10 digits after point, like 3.1415900000
std::cout << f << '\n';
std::cout.setf( std::ios::fixed, std:: ios::floatfield ); // floatfield set to fixed
std::cout << f << '\n';
To remove any trailing zeroes, you can use
std::cout.precision(0);
Basically, you can set:
std::cout.precision(6); // 6 digits
or whatever value you need. Or:
std::cout << std::setprecision(5) << my_double_value << std::endl;
iostream provides a setprecision function:
double f =3.14159;
std::cout << std::setprecision(5) << f << '\n';
std::cout << std::setprecision(9) << f << '\n';
std::cout << std::fixed;
std::cout << std::setprecision(5) << f << '\n';
std::cout << std::setprecision(9) << f << '\n'
Output will be:
3.1416
3.14159
3.14159
3.141590000
There isn't an "actual number of decimal places". Double precision has a number of binary places but these don't map reliably into a number of decimal places. An easy example is 1.0/10,0 which should be 0.1 but is actually a number quite close to 0.1; how many decimal places you show for sums such as these is thus not a quality of the double itself but rather of how many decimal places you want to show.
How you can truncate to the number you want has been discussed in the other answers.
This will work:
printf("%g",value);

different values of std::floor function for arguments with same value but different types

Consider the following:
#include <iostream>
#include <cmath>
int main()
{
using std::cout;
using std::endl;
const long double be2 = std::log(2);
cout << std::log(8.0) / be2 << ", " << std::floor(std::log(8.0) / be2)
<< endl;
cout << std::log(8.0L) / be2 << ", " << std::floor(std::log(8.0L) / be2)
<< endl;
}
Outputs
3, 2
3, 3
Why does the output differ? What am I missing here?
Also here is the link to codepad: http://codepad.org/baLtYrmy
And I'm using gcc 4.5 on linux, if that's important.
When I add this:
cout.precision(40);
I get this output:
2.999999999999999839754918906642444653698, 2
3.00000000000000010039712117215771058909, 3
You're printing two values that are very close to, but not exactly equal to, 3.0. It's the nature of std::floor that its results can differ for values that are very close together (mathematically, it's a discontinuous function).
#include <iostream>
#include <cmath>
#include <iomanip>
int main()
{
using std::cout;
using std::endl;
const long double be2 = std::log(2);
cout << setprecision (50)<<std::log(8.0)<<"\n";
cout << setprecision (50)<<std::log(8.0L)<<"\n";
cout << setprecision (50)<<std::log(8.0) / be2 << ", " << std::floor(std::log(8.0) / be2)
<< endl;
cout << setprecision (50)<< std::log(8.0L) / be2 << ", " << std::floor(std::log(8.0L) / be2)
<< endl;
return 0;
}
The output is:
2.0794415416798357476579894864698871970176696777344
2.0794415416798359282860714225549259026593063026667
2.9999999999999998397549189066424446536984760314226, 2
3.0000000000000001003971211721577105890901293605566, 3
If you check the output here, you will notice that there is a slight difference in the precision of the two outputs. These roundoff errors usually kick in on operations on float & double here while performing floor() and the results that appear are not what one feels they should be.
It is important to remember two attributes Precision & Rounding when you are working with float or double numbers.
You might want to read more about it in my answer here, the same reasoning applies here as well.
To expand on what Als is saying-
In the first case you are dividing an 8-byte double precision value by a 16-byte long double. In the second case you are dividing a 16-byte long double by a 16-byte long double. This results in a very small roundoff error which can be seen here:
cout << std::setprecision(20) << (std::log(8.0) / be2) << std::endl;
cout << std::setprecision(20) << (std::log(8.0L) / be2) << std::endl;
which yields:
2.9999999999999998398
3.0000000000000001004
Edit to say: in this case, sizeof is your friend (To see the difference in precision):
sizeof(std::log(8.0)); // 8
sizeof(std::log(8.0L)); // 16
sizeof(be2); // 16