remainder() doesn't work in if statement C++ - c++11

The code below should output the each 10th term (0.0, 10.0, 20.0, etc...) till 100.0. But it outputs only "0". Does anyone know what's the problem?
include <iostream>
include <cmath>
using namespace std;
for (double t = 0.0; t < 100.0; t += 0.1)
{
if (remainder(t, 10.0) == 0)
{
cout << t << "\n";
}
}

You're working with floating-point numbers which have inherent inaccuracy. remainder returns a float value and checking the value exactly to 0 with == doesn't always work.
You need to use a tolerance and see if the remainder is in the bounds of the tolerance as:
#include <iostream>
#include <cmath>
int main()
{
for (double t = 0.0; t <= 100.0; t += 0.1)
{
if (std::abs(std::remainder(t, 10.0)) <= 0.001)
{
std::cout << t << "\n";
}
}
}
Note: further reading.

Related

<random> generates same number in Windows, but not in Linux

I do not why, but in Windows (with MinGW) this code generates for 3/4 time the same pseudo-random number.
I think that is because I set badly the seed, but I can not correct it.
Thank you for your help.
Here there is the code:
#include <iostream>
#include <random>
#include <chrono>
int main()
{
double Nprove = 50.0;
double p = 0.2;
const int Ncampioni = 100; // number of samples
int cappa = 0;
double sample[Ncampioni];
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
std::mt19937 gen(seed);
std::binomial_distribution<> d(Nprove, 0.9);
for(cappa = 0; cappa < Ncampioni; cappa = cappa +1){
sample[cappa] = d(gen);
std::cout << cappa << "," << sample[cappa] << std::endl;
}
}

wrong result boost gmp float

I need to compute 5^64 with boost multiprecision library which should yield 542101086242752217003726400434970855712890625 but boost::multiprecision::pow() takes mpfloat and gives 542101086242752217003726392492611895881105408.
However If I loop and repeatedly multiply using mpint I get correct result.
Is it a bug ? or I am using boost::multiprecision::pow() in a wrong way ? or I there is an alternative of using boost::multiprecision::pow() ?
#include <iostream>
#include <string>
#include <boost/multiprecision/gmp.hpp>
typedef boost::multiprecision::mpz_int mpint;
typedef boost::multiprecision::number<boost::multiprecision::gmp_float<4> > mpfloat;
int main(){
mpfloat p = boost::multiprecision::pow(mpfloat(5), mpfloat(64));
std::cout << p.template convert_to<mpint>() << std::endl;
mpint res(1);
for(int i = 0; i < 64; ++i){
res = res * 5;
}
std::cout << res << std::endl;
}

Odd numbers recursively? code currently finds even nums

Just wondering if there is a line change I can make in order to find odds instead of evens? Here's what I got:
#include <iostream>
#include <conio.h>
#include "stdafx.h"
void numOdd(int x, int y)
{
std::cout << x << " ";
if (x < y)
{
numOdd(x + 2, y);
}
}
int main()
{
int x = 0;
int y = 0;
std::cout << "Up to what num to find odd nums? " << std::endl;
std::cin >> y;
numOdd(x, y);
_getch();
}
Initialize x to 1 instead of 0.
Aso, be advised that recursion is not a great fit for this problem; a simple loop would be more appropriate.

C++11 app that uses dispatch_apply not working under Mac OS Sierra

I had a completely functioning codebase written in C++11 that used Grand Central Dispatch parallel processing, specifically dispatch_apply to do the basic parallel for loop for some trivial game calculations.
Since upgrading to Sierra, this code still runs, but each block is run in serial -- the cout statement shows that they are being executed in serial order, and CPU usage graph shows no parallel working on.
Queue is defined as:
workQueue = dispatch_queue_create("workQueue", DISPATCH_QUEUE_CONCURRENT);
And the relevant program code is:
case Concurrency::Parallel: {
dispatch_apply(stateMap.size(), workQueue, ^(size_t stateIndex) {
string thisCode = stateCodes[stateIndex];
long thisCount = stateCounts[stateIndex];
GameResult sliceResult = playStateOfCode(thisCode, thisCount);
results[stateIndex] = sliceResult;
if ((stateIndex + 1) % updatePeriod == 0) {
cout << stateIndex << endl;
}
});
break;
}
I strongly suspect that this either a bug, but if this is GCD forcing me to use new C++ methods for this, I'm all ears.
I'm not sure if it is a bug in Sierra or not. But it seems to work if you explicitly associate a global concurrent queue as target:
dispatch_queue_t target =
dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0);
dispatch_queue_t workQueue =
dispatch_queue_create_with_target("workQueue", DISPATCH_QUEUE_CONCURRENT, target);
// ^~~~~~~~~~~ ^~~~~~
Here is a working example
#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>
#include <sstream>
#include <dispatch/dispatch.h>
void load_problem(const std::string, std::vector<std::pair<double,double>>&);
int main() {
// n-factor polynomial - test against a given problem provided as a set of space delimited x y values in 2d.txt
std::vector<std::pair<double,double>> problem;
std::vector<double> test = {14.1333177226503,-0.0368874860476915,
0.0909424058436257,2.19080982673558,1.24632025036125,0.0444549880462031,
1.06824631867947,0.551482840616757, 1.04948148731933};
load_problem("weird.txt",problem); //a list of space delimited doubles representing x, y.
size_t a_count = test.size();
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
__block double diffs = 0.0; //sum of all values..
dispatch_apply(problem.size(), queue, ^(size_t i) {
double g = 0;
for (size_t j=0; j < a_count - 1; j++) {
g += test[j]*pow(problem[i].first,a_count - j - 1);
}
g += test[a_count - 1];
diffs += pow(g - problem[i].second,2);
});
double delta = 1/(1+sqrt(diffs));
std::cout << "test: fit delta: " << delta << std::endl;
}
void load_problem(const std::string file, std::vector<std::pair<double,double>>& repo) {
repo.clear();
std::ifstream ifs(file);
if (ifs.is_open()) {
std::string line;
while(getline(ifs, line)) {
double x= std::nan("");
double y= std::nan("");
std::istringstream istr(line);
istr >> std::skipws >> x >> y;
if (!isnan(x) && !isnan(y)) {
repo.push_back({x, y});
};
}
ifs.close();
}
}

Interleave random numbers

I would like to interleave a random number with some alphanumeric characters, for example: HELLO mixed with the random number 25635 → H2E5L6L3O5. I know %1d controls the spacing, although I'm not sure how to interleave text between the random numbers or how accomplish this.
Code:
int main(void) {
int i;
srand(time(NULL));
for (i = 1; i <= 10; i++) {
printf("%1d", 0 + (rand() % 10));
if (i % 5 == 0) {
printf("\n");
}
}
return 0;
}
btw - if my random number generator isn't very good i'm open to suggestions - thanks
If you're okay with using C++11, you could use something like this:
#include <iostream>
#include <random>
#include <string>
int main() {
std::random_device rd;
std::default_random_engine e1(rd());
std::uniform_int_distribution<int> uniform_dist(0, 9);
std::string word = "HELLO";
for (auto ch : word) {
std::cout << ch << uniform_dist(e1);
}
std::cout << '\n';
}
...which produces e.g.:
H3E6L6L1O5
If you're stuck with an older compiler, you could use rand and srand from the standard C library for your random numbers:
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
int main() {
std::srand(std::time(NULL));
std::string word = "HELLO";
for (int i = 0; i < word.size(); ++i) {
std::cout << word[i] << (rand() % 10);
}
std::cout << '\n';
}

Resources