Issue with fmod with doubles - c++

It would seem fmod(x,1) where x is a double gives the wrong result, as output by the line:
std::cout << fmod(min, 1) << "|" << fmod(max, 1) << std::endl;
I forgot the name for what you call this, but this is the smallest amount of code necessary to illustrate my problem:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <time.h>
#include <math.h>
const int deviation = 3;
void weightedRandomNumber(double min, double max);
int main() {
srand(time(nullptr));
std::cout.precision(16);
std::cout << 123.1 << "|" << 2789.3234 << std::endl;
weightedRandomNumber(123.1, 2789.3234);
system("pause");
return 0;
}
void weightedRandomNumber(double min, double max) {//inclusive
int multiplier = 1;
std::cout << min << "|" << max << std::endl;
while (fmod(min, 1) > 0 || fmod(max, 1) > 0) {
std::cout << min << "|" << max << std::endl;
std::cout << fmod(min, 1) << "|" << fmod(max, 1) << std::endl;
min *= 10;
max *= 10;
multiplier++;
}
std::cout << min << "|" << max << std::endl;
std::cout << multiplier << std::endl;
}
The outputs I get when I run the code are as such:
123.1|2789.3234
123.1|2789.3234
123.1|2789.3234
0.09999999999999432|0.3234000000002197
1231|27893.234
0|0.2340000000040163
12310|278932.34
0|0.3400000000256114
123100|2789323.4
0|0.400000000372529
1231000|27893234
0|3.725290298461914e-09
12310000|278932340.0000001
0|5.960464477539063e-08
123100000|2789323400
0|4.76837158203125e-07
1231000000|27893234000
0|3.814697265625e-06
12310000000|278932340000.0001
0|6.103515625e-05
123100000000|2789323400000
0|0.00048828125
1231000000000|27893234000000
0|0.00390625
12310000000000|278932340000000
0|0.03125
123100000000000|2789323400000001
0|0.5
1231000000000000|2.7893234e+16
14
Other than this I don't quite know what to say, if I have missed anything necessary please comment so I can amend my question.

The issue is not with fmod, which is giving the highest precision results it can. The issue is with cout precision not behaving like you expect, combined with "rounding" because a double cannot store 0.1 accurately enough to represent what cout considers a precision of 16.
This code demonstrates the issue. The rounding actually occurs when you assign 123.1 to a double, but because of the 3 digits to the left is not visible until it becomes a smaller number.
int main() {
std::cout.precision(16);
std::cout << (123.1L - 123L);
}
output:
0.09999999999999432
Actually....this illustrates the problem even more succinctly:
int main() {
std::cout.precision(20);
std::cout << 123.1;
}
123.09999999999999432
Further reading from the comments on your question:
Is floating point math broken?
Also, for the vast majority of scenarios, a double is more than fine. For accurate, recursive math, you'd want to consider a heavy-duty math library, or even a math-specialized language.
Further further reading:
http://www.boost.org/doc/libs/1_62_0/libs/math/doc/html/math_toolkit/high_precision/why_high_precision.html

Related

C++ pow behaviour with negative vector size calculations

After calling pow function with the argument as in the code bellow
it produces some high number as if it was accessing some invalid memory location.
I have no idea why this happens and any help would be greatly appreciated.
#include <iostream>
#include <vector>
#include <math.h>
using namespace std;
int main() {
vector<vector<int>> G = {
{1, 2, 3},
{0, 4}
};
cout << pow(G[1].size() - G[0].size(), 2) << endl;
return 0;
}
This prints 1.84467e+019.
The type of .size() is unsigned and you can not simply subtract them when the left operand is less than the right one.
Try this:
cout << pow((long) G[1].size() - (long)G[0].size(), 2) << endl;
~~~~~~ ~~~~~~
However, this solution is based on the assumption that casting the result of .size() fits into a signed long.
If you want a more defensive code, try this one:
size_t size_diff(size_t s0, size_t s1)
{
return s0 < s1? (s1 - s0) : (s0 - s1);
}
int main() {
// ...
cout << pow(size_diff(G[1].size(), G[0].size()), 2) << endl;
}
In addition to the accepted answer, I'd like to note that in C++20 we'll have std::ssize() free function that returns size as a signed type value. Then
std::pow(std::ssize(G[1]) - std::ssize(G[0]), 2)
will produce the correct result without explicit type casts.
Since pow takes a floating point value as its first argument, I'd suggest letting the compiler decide the right promotion by adding the difference to 0.0 (or 0.0L):
#include <iostream>
#include <cstdint>
#include <cmath>
using namespace std;
int main()
{
std::string name;
/// 52 of 64 bits used
uint64_t n1 = 0x000ffffffffffffd;
uint64_t n2 = 0x000fffffffffffff;
cout << "plain: " << n1 - n2 << endl;
cout << "float: " << (float)n1 - (float)n2 << endl;
cout << "double: " << (double)n1 - (double)n2 << endl;
cout << "long double: " << (long double)n1 - (long double)n2 << endl;
cout << "0.0+: " << 0.0 + n1 - n2 << endl;
cout << "0.0L+: " << 0.0L + n1 - n2 << endl;
cout << "pow(plain, 2): " << pow(n1-n2, 2) << endl;
cout << "pow(0.0+diff, 2): " << pow(0.0+n1-n2, 2) << endl;
cout << "pow(0.0L+diff, 2): " << pow(0.0L+n1-n2, 2) << endl;
}
The output
plain: 18446744073709551614
float: 0
double: -2
long double: -2
0.0+: -2
0.0L+: -2
pow(plain, 2): 3.40282e+38
pow(0.0+diff, 2): 4
pow(0.0L+diff, 2): 4
shows that plain subtraction goes wrong. Even casting to float doesn't suffice because float provides only a 23-bit mantissa.
The decision whether to use 0.0 or 0.0L for differences of size_t values returned by real std::vector::size() calls is theoretical for processes with address spaces below 4.5 Petabytes.
So I think the following will do:
cout << pow(0.0 + G[1].size() - G[0].size(), 2) << endl;

fmod telling me fractional part of 1 is 1

I'm trying to check if a double variable p is approximately equal to an integer. At some point in my code I have
double ip;
cout << setprecision(15) << abs(p) << " " << modf(abs(p), &ip) << endl;
And for a given run I get the printout
1 1
This seems to say that the fractional part of 1 is 1, am I missing something here or could there be some roundoff problem etc?
Note: I'm not including the whole code since the origin of p is complicated and I'm just asking if this is a familiar issue
could there be some roundoff problem etc?
There certainly could. If the value is very slightly less than 1, then both its value and its fractional part could be rounded to 1 when displayed.
the origin of p is complicated
Then it's very likely not to be an exact round number.
You are testing a nearly-1-value, so precision of 15 is not enough to describe it unambiguously.
This code shows your problem clearly:
#include <iostream>
#include <iomanip>
#include <cmath>
#include <limits>
using namespace std;
int main() {
double ip, d = nextafter(1., .0); // Get a double just smaller than 1
const auto mp = std::numeric_limits<double>::max_digits10;
cout << 15 << ": " << setprecision(15)
<< abs(d) << " " << modf(abs(d), &ip) << '\n';
cout << mp << ": " << setprecision(mp)
<< abs(d) << " " << modf(abs(d), &ip) << '\n';
}
On coliru: http://coliru.stacked-crooked.com/a/e00ded79c1727299
15: 1 1
17: 0.99999999999999989 0.99999999999999989

C++ How do I stop outputting the decimal and zero of a number like 5.0 using std::cout

I was about to ask this question, and found a few more to ask.
How (according to the top answer) would I then proceed to only display this precision for a single call to cout, and then disable it thereafter?
Say I want to show precision for the first three calls, but not the last:
(I named a variable with the same name as the "fixed" format specifier in order to experiment)
#include <iostream>
int main(){
using namespace std;
int spam = 5;
double flak = 5.0;
double result = spam * flak;
double fixed = 42;
cout.precision(1);
cout << std::fixed << spam + flak << endl;
cout << result << endl;
cout << flak << endl;
cout << fixed;
return 0;
}
You can invoke the precision function again to re-apply it like so:
int main(){
using namespace std;
int spam = 5;
double flak = 5.0;
double result = spam * flak;
double fixed = 42;
cout.precision(1);
cout << std::fixed << spam + flak << endl;
cout << result << endl;
cout << flak << endl;
cout.precision(3);
cout << fixed;
return 0;
}
Another way to do it is to use the <iomanip> header to use the std::setprecision() function and passing it to std::cout, so it would be similar to doing this:
#include <iomanip>
#include <iostream>
int main() {
int spam = 5;
double flak = 5.0;
double result = spam * flak;
double fixed = 42;
std::cout << std::fixed << spam + flak << std::endl;
std::cout << std::setprecision(1) << result << '\n' << flak << std::endl;
std::cout << std::setprecision(0) << fixed;
return 0;
}
Not sure what you want. But C++ provides some ways to control the state of stream.
std::streamsize prec = cout.precision(); // store current precision setting
// some print here
std::cout.precision(prec) // Roll-back
One (ugly) way would be to cast it to int before the cout if you dont want to see the decimal places.
Something like (C style - still ok for primitive types)
cout << (int)flak << endl;
or ( C++ style - recommended, especially for non primitive types like classes)
cout << static_cast<int>(flak) << endl;
This will only change what cout sees, not the variable itself.

How to output with 3 digits after the decimal point with C++ stream?

Given a variable of float type, how to output it with 3 digits after the decimal point, using iostream in C++?
Use setf and precision.
#include <iostream>
using namespace std;
int main () {
double f = 3.14159;
cout.setf(ios::fixed,ios::floatfield);
cout.precision(3);
cout << f << endl;
return 0;
}
This prints 3.142
This one does show "13.142"
#include <iostream>
#include <iomanip>
using namespace std;
int main(){
double f = 13.14159;
cout << fixed;
cout << setprecision(3) << f << endl;
return 0;
}
You can get fixed number of fractional digits (and many other things) by using the iomanip header. For example:
#include <iostream>
#include <iomanip>
int main() {
double pi = 3.141592653589;
std::cout << std::fixed << std::setprecision(2) << pi << '\n';
return 0;
}
will output:
3.14
Note that both fixed and setprecision change the stream permanently so, if you want to localise the effects, you can save the information beforehand and restore it afterwards:
#include <iostream>
#include <iomanip>
int main() {
double pi = 3.141592653589;
std::cout << pi << '\n';
// Save flags/precision.
std::ios_base::fmtflags oldflags = std::cout.flags();
std::streamsize oldprecision = std::cout.precision();
std::cout << std::fixed << std::setprecision(2) << pi << '\n';
std::cout << pi << '\n';
// Restore flags/precision.
std::cout.flags (oldflags);
std::cout.precision (oldprecision);
std::cout << pi << '\n';
return 0;
}
The output of that is:
3.14159
3.14
3.14
3.14159
If you want to print numbers with precision of 3 digits after decimal, just add the following thing before printing the number cout << std::setprecision(3) << desired_number. Don't forget to add #include <iomanip> in your code.
In general, precision is the maximum number of digits displayed. The manipulator fixed will set up the output stream for displaying values in fixed format. In fixed the precision is the number of digits after the decimal point. The setprecision allows setting the precision used for displaying floating-point values, it takes an integer argument.
cout << fixed;
cout << setprecision(3) << f << endl;
You may unset fixed using cout.unsetf(ios::fixed)

Problem with square root of (2147483647) in c++

I am calculating square root of 2147483647 by sqrt function.and the result must be a float value 46340.95 but my code returns the value 46341.
Can anyone tell me where is the problem?
i am using code :
double x=2147483647.0;
double y=sqrt(x);
cout<< y;
I get that same result. But, if I inject a setprecision, I get the right value:
#include <iostream>
#include <iomanip>
#include <cmath>
int main (void) {
double x=2147483647.0;
double y=sqrt(x);
std::cout << std::setprecision(10) << y << std::endl;
return 0;
}
gives me:
46340.95
In fact, if you use the folowing code:
#include <iostream>
#include <iomanip>
#include <cmath>
int main (void) {
double x=2147483647.0;
double y=sqrt(x);
std::cout << y << std::endl;
std::cout << std::setprecision(0) << std::fixed << y << std::endl;
std::cout << std::setprecision(1) << std::fixed << y << std::endl;
std::cout << std::setprecision(2) << std::fixed << y << std::endl;
std::cout << std::setprecision(3) << std::fixed << y << std::endl;
return 0;
}
you get:
46341
46341
46341.0
46340.95
46340.950
So it appears that the default setting (at least for my environment) is a precision of zero.
If you want a specific format, I suggest you explicitly request it.
The default precision for cout is not sufficient to show the fractional part of your result. Your result is 46340.95, which rounded to six digits of precision is 43641.0, and is displayed as 43641 by cout. To show more precision, set the precision of cout first:
double x=2147483647.0;
double y=sqrt(x);
cout.precision(9);
cout<< y;
On my system this shows a result of 46340.95.
This trivial code yields 46340.9:
#include <cmath>
#include <iostream>
int main()
{
float x = std::sqrt(2147483647);
std::cout << x << std::endl;
return 0;
}
What does your code look like?
(Just for the record: tested using GCC (g++) 4.5.2 on MacOS X 10.6.6.)