It seem that the MSVC Compiler treats signed and unsigned overflow differnetly. When casting a double value that exceeds the maximum integer value, the result is the smallest possible integer value (always the same). When casting to unsigned int, the cast produces an overflow as expected (maximum unsigned int value + 1 produces 0, maximum unsigned int + 2 produces 1, ...)
Can someone explain the behaviour of the compiler, or is it a bug?
Tested compilers MSVC 10 and 14
#define BOOST_TEST_MODULE Tests
#include <boost/test/unit_test.hpp>
#include <climits>
#include <iostream>
BOOST_AUTO_TEST_CASE(test_overflow_signed) {
double d_int_max_1 = INT_MAX + 1.; //2147483647 + 1
double d_int_max_2 = INT_MAX + 2.; //2147483647 + 2
BOOST_CHECK((int)(2147483648.) != (int)(2147483649.)); //succeeds (overflows to -2147483648 and -2147483647)
BOOST_CHECK((int)(d_int_max_1) != (int)(d_int_max_2)); //fails (both values overflow to -2147483648)
std::cout << "(int)(2147483648.) == " << (int)(2147483648.) << std::endl; //-2147483648
std::cout << "(int)(2147483649.) == " << (int)(2147483649.) << std::endl; //-2147483647
std::cout << "(int)(d_int_max_1) == " << (int)(d_int_max_1) << std::endl; //-2147483648
std::cout << "(int)(d_int_max_2) == " << (int)(d_int_max_2) << std::endl; //-2147483648
}
BOOST_AUTO_TEST_CASE(test_overflow_unsigned) {
double d_int_max_1 = UINT_MAX + 1.;//4294967295 + 1
double d_int_max_2 = UINT_MAX + 2.;//4294967295 + 2
//BOOST_CHECK((unsigned int)(4294967296.) != (unsigned int)(4294967297.)); //compiler fails (!= truncation of constant value)
BOOST_CHECK((unsigned int)(d_int_max_1) != (unsigned int)(d_int_max_2)); //succeeds (overflows to 0 and 1)
std::cout << "(unsigned int)(d_int_max_1) == " << (unsigned int)(d_int_max_1) << std::endl; //0
std::cout << "(unsigned int)(d_int_max_2) == " << (unsigned int)(d_int_max_2) << std::endl; //1
}
[conv.fpint]/1 A prvalue of a floating point type can be converted to a prvalue of an integer type. The conversion truncates; that is, the fractional part is discarded. The behavior is undefined if the truncated value cannot be
represented in the destination type.
Emphasis mine. Since the behavior is undefined, any outcome whatsoever is correct.
Related
I'm currently working on implementing memoization into the Grid Traveler problem. It looks like it should work, but it's still sticking on bigger cases like (18,18). Did I miss something, or are maps not the right choice for this kind of problem?
P.S. I'm still very new at working with maps.
#include <iostream>
#include <unordered_map>
#include <string>
using namespace std;
uint64_t gridTravMemo(int m, int n, unordered_map<string, uint64_t>grid)
{
string key;
key = to_string(m) + "," + to_string(n);
if (grid.count(key) > 0)
return grid.at(key);
if (m == 1 && n == 1)
return 1;
if (m == 0 || n == 0)
return 0;
grid[key] = gridTravMemo(m-1, n, grid) + gridTravMemo(m, n-1, grid);
return grid.at(key);
}
int main()
{
unordered_map<string, uint64_t> gridMap;
cout << gridTravMemo(1, 1, gridMap) << endl;
cout << gridTravMemo(2, 2, gridMap) << endl;
cout << gridTravMemo(3, 2, gridMap) << endl;
cout << gridTravMemo(3, 3, gridMap) << endl;
cout << gridTravMemo(18, 18, gridMap) << endl;
return 0;
}
The point of memorized search is to optimize running time by returning any previous values that you have calculated. This way, instead of a brute force algorithm, you can reach a runtime of O(N*M).
However, you are passing your unordered_map<string, uint64_t>grid as a parameter for your depth-first search.
You are calling grid[key] = gridTravMemo(m-1, n, grid) + gridTravMemo(m, n-1, grid); This means that your search is splitting into two branches. However, the grid in these two branches are different. This means that the same state can be visited in two separate branches, leading to a runtime more like O(2^(N*M)).
When you're testing an 18x18 grid, this definitely will not run quickly enough.
This is relatively easy to fix. Just declare grid as a global variable. This way its values can be used between different branches.
Try something like this:
#include <iostream>
#include <unordered_map>
#include <string>
using namespace std;
unordered_map<string, uint64_t> grid;
uint64_t gridTravMemo(int m, int n)
{
string key;
key = to_string(m) + "," + to_string(n);
if (grid.count(key) > 0)
return grid.at(key);
if (m == 1 && n == 1)
return 1;
if (m == 0 || n == 0)
return 0;
grid[key] = gridTravMemo(m-1, n) + gridTravMemo(m, n-1);
return grid.at(key);
}
int main()
{
cout << gridTravMemo(1, 1) << endl;
grid.clear()
cout << gridTravMemo(2, 2) << endl;
grid.clear()
cout << gridTravMemo(3, 2) << endl;
grid.clear()
cout << gridTravMemo(3, 3) << endl;
grid.clear()
cout << gridTravMemo(18, 18) << endl;
return 0;
}
I'm having a problem with boost cpp_dec_float division producing wrong results.
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <iostream>
int main()
{
using namespace boost::multiprecision;
using namespace std;
cpp_dec_float_50 a = 15; // exactly 5 * 3
cpp_dec_float_50 b = 3;
cpp_dec_float_50 c = a / b; // should be exactly 5
cpp_dec_float_50 d = 5;
cout << setprecision(std::numeric_limits<cpp_dec_float_50>::max_digits10);
cout << "c: " << c << endl;
cout << "d: " << d << endl;
cout << "c == d: " << (c == d ? "true" : "false") << endl;
return 0;
}
This produces
c: 4.999999999999999999999999999999999999999999999999999999999999999999999995
d: 5
c == d: false
I saw this question which discusses it for a fractional result. While some comments there were trying to explain it as an effect of truncation, that was not convincing IMO.
And in my case, all values, including the result, are integers, so if there is a decimal arithmetic performed, no truncation should happen.
Any ideas to make boost produce the correct/expected results?
I'm trying to create a list which contains 10 unique random numbers between 1 and 20 by using a recursive function. Here is the code.
Compiler: GNU g++ 10.2.0 on Windows
Compiler flags: -DDEBUG=9 -ansi -pedantic -Wall -std=c++11
#include <iostream>
#include <vector>
#include <algorithm>
#include <time.h>
using namespace std;
vector<int> random (int size, int range, int randnum, vector<int> randlist ) {
if (size < 1) {
cout << "returning...(size=" << size << ")" << endl;
return randlist;
}
else {
if (any_of(randlist.begin(), randlist.end(),[randnum](int elt) {return randnum == elt;})){
cout << "repeating number: " << randnum << endl;
random(size, range, rand() % range + 1, randlist);
return randlist;
}
else {
cout << "size " << size << " randnum " << randnum << endl;
randlist.push_back(randnum);
random(size-1, range, rand() % range + 1, randlist);
return randlist; }
}
}
int main (int argc, char *argv[]) {
srand (time(NULL));
vector<int> dummy{};
vector<int> uniqrandnums = random(10, 20, (rand() % 20) + 1, dummy );
cout << "here is my unique random numbers list: " ;
for_each(uniqrandnums.begin(),uniqrandnums.end(), [](int n){cout << n << ' ';});
}
To keep track of the unique random numbers, I've added 2 cout lines inside the recursive function random. The recursive function seems to operate correctly but it can't return back the resulting vector<int list randlist correctly; it seems to return a list with just the first random number it found.
Note: Reckoning that the function would finally return from here:
if (size < 1) {
cout << "returning...(size=" << size << ")" << endl;
return randlist;
}
I haven't initially added the last 2 return randlist; lines inside the recursive function but as is, it gave compilation warning control reaches end of non-void function [-Wreturn-type] That's why I've added those 2 return statements but it made just the warnings go away and it didn't help operate correctly.
Question: How to arrange the code so the recursive function random returns the full list in a correct manner?
The issue is that you are discarding the result of recursive calls to randlist(). In the two places where you call:
random(..., randlist);
return randlist;
Replace that with:
return random(..., randlist);
I am using the boost::multiprecision library for decimal float types, and wish to compare two floats to the specified precision.
However, cpp_dec_float seems to compare the number not to the specified precision, but also includes the guard digits:
#include <iostream>
#include <boost/multiprecision/cpp_dec_float.hpp>
//#include <boost/math/special_functions.hpp>
typedef boost::multiprecision::number<boost::multiprecision::cpp_dec_float<50> > flp_type;
int main(int argc, char* argv[])
{
// 50 decimal digits
flp_type sqrt2("1.4142135623730950488016887242096980785696718753769");
// Contains calculated guard digits
flp_type result(boost::multiprecision::sqrt(flp_type("2")));
// The 50 digits of precision actually ompare equal
std::cout << std::setprecision(50) << sqrt2 << std::endl;
std::cout << std::setprecision(50) << result << std::endl;
// I want this to compare to the specified precision of the type, not the guard digits
std::cout << (result==sqrt2) << std::endl;
return 0;
}
Output:
1.4142135623730950488016887242096980785696718753769
1.4142135623730950488016887242096980785696718753769
0
Expected:
1.4142135623730950488016887242096980785696718753769
1.4142135623730950488016887242096980785696718753769
1
See on Coliru
I have tried to "truncate" with precision(), but to no avail.
Is there a way to compare the two numbers without resorting to epsilon comparisons?
If you strip the guard bits, you effectively cripple the fidelity of the type as intended.
A surefire way would be to use (de)serialization, really.
So I suggest
Live On Coliru
// Either
std::cout << std::numeric_limits<flp_type>::epsilon() << "\n";
std::cout << (abs(result-sqrt2) < std::numeric_limits<flp_type>::epsilon()) << std::endl;
// Or
result = flp_type { result.str(49, std::ios::fixed) };
std::cout << (result==sqrt2) << std::endl;
Note that the epsilon is 1e-49 there
Prints
1.4142135623730950488016887242096980785696718753769
1.4142135623730950488016887242096980785696718753769
1e-49
1
1
Obviously the epsilon() based comparison would be appear the more efficient
bool is_equal = abs(result-sqrt2) < std::pow(10, -std::numeric_limits< flp_type >::digits10 );
I'm playing with the constexpr keyword and coded the following simple program:
#include <iostream>
using namespace std;
template<typename T>
constexpr bool is_equal(T const* array1, T const* array2, size_t len)
{
return array1 == array2 || (len ? array1[len - 1] == array2[len - 1] && is_equal<T>(array1, array2, len - 1) : true);
}
template<typename T, size_t N1, size_t N2>
constexpr bool is_equal(T const (&array1)[N1], T const (&array2)[N2])
{
return N1 == N2 && is_equal<T>(array1, array2, N1);
}
template<typename T, size_t N>
constexpr size_t arraylength(T const (&array)[N])
{
return N;
}
constexpr size_t stringlength(char const* str, size_t len=0)
{
return str ? (*str ? stringlength(str + 1, len + 1) : len) : 0;
}
constexpr size_t min(size_t one, size_t another)
{
return one < another ? one : another;
}
constexpr size_t min_length(char const* str1, char const* str2)
{
return min(stringlength(str1), stringlength(str2));
}
template<typename T, size_t N1, size_t N2>
constexpr size_t min_length(T const (&array1)[N1], T const (&array2)[N2])
{
return min(N1, N2);
}
template<bool cond=false>
struct to_num
{
enum {value=0};
};
template<>
struct to_num<true>
{
enum {value=42};
};
template<size_t init>
struct two_times
{
enum {value=init*2};
};
static constexpr char x[]{"One string"};
static constexpr char y[]{"One string"};
static constexpr int a[]{1,2,3,4};
static constexpr int b[]{1,2,3,4};
static constexpr int const* const c = &a[0];
static constexpr int const* const d = &b[0];
int main()
{
cout << "The two literals are equal: " << to_num< is_equal("One string", "One string") >::value << endl; // COMPILES AND WORKS IN GCC BUT NOT IN CLANG
cout << "The two variables x & y are equal: " << to_num< is_equal(x, y) >::value << endl;
cout << "Pointers a & c are equal: " << to_num< a == c >::value << endl;
cout << "Pointers b & c are equal: " << to_num< b == c >::value << endl;
cout << "Pointers c & d are equal: " << to_num< c == d >::value << endl;
cout << "The contents of c & d is the same: " << to_num< is_equal(c, d, arraylength(a)) >::value << endl;
cout << "Pointers a & b are equal: " << to_num< a == b >::value << endl;
cout << "The contents of a & b is the same: " << to_num< is_equal(a, b) >::value << endl;
cout << "String x contains " << two_times< stringlength(x) >::value / 2 << " characters" << endl; // COMPILES AND WORKS IN CLANG BUT NOT IN GCC
cout << "String literal contains " << two_times< stringlength("literal") >::value / 2 << " characters" << endl; // COMPILES AND WORKS IN CLANG BUT NOT IN GCC
cout << "Array literal contains " << two_times< arraylength("literal") >::value / 2 << " values" << endl;
return 0;
}
As the comments remark, some code compiles and works ok with g++ but not with clang++ and other compiles and work ok with clang++ but not with g++
The gcc error is:
comaprison.cpp: In function ‘int main()’:
comaprison.cpp:97:62: in constexpr expansion of ‘stringlength(((const char*)(& x)), 0ul)’
comaprison.cpp:29:55: in constexpr expansion of ‘stringlength((str + 1u), (len + 1ul))’
comaprison.cpp:97:64: error: ‘((((const char*)(& x)) + 1u) != 0u)’ is not a constant expression
cout << "String x contains " << two_times< stringlength(x) >::value / 2 << " characters" << endl;
^
comaprison.cpp:97:64: note: in template argument for type ‘long unsigned int’
comaprison.cpp:98:76: in constexpr expansion of ‘stringlength(((const char*)"literal"), 0ul)’
comaprison.cpp:29:55: in constexpr expansion of ‘stringlength((str + 1u), (len + 1ul))’
comaprison.cpp:98:78: error: ‘((((const char*)"literal") + 1u) != 0u)’ is not a constant expression
cout << "String literal contains " << two_times< stringlength("literal") >::value / 2 << " characters" << endl; // COMPILES AND WORKS IN CLANG BUT NOT IN GCC
^
comaprison.cpp:98:78: note: in template argument for type ‘long unsigned int’
and the clang++ one is:
comaprison.cpp:89:55: error: non-type template argument is not a constant expression
cout << "The two literals are equal: " << to_num< is_equal("One string", "One string") >::value << ...
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
comaprison.cpp:8:19: note: subexpression not valid in a constant expression
return array1 == array2 || (len ? array1[len - 1] == array2[len - 1] && is_equal<T>(array1, array2...
^
comaprison.cpp:14:24: note: in call to 'is_equal(&"One string"[0], &"One string"[0], 11)'
return N1 == N2 && is_equal<T>(array1, array2, N1);
^
comaprison.cpp:89:55: note: in call to 'is_equal("One string", "One string")'
cout << "The two literals are equal: " << to_num< is_equal("One string", "One string") >::value << ...
^
1 error generated.
g++ is "gcc version 4.8.1 (Ubuntu/Linaro 4.8.1-10ubuntu9)",
clang++ is "Ubuntu clang version 3.4-1ubuntu1 (trunk) (based on LLVM 3.4)"
Both in a x86_64 linux.
The command lines are:
clang++ -std=c++11 -o comaprison comaprison.cpp
g++ -std=c++11 -o comaprison comaprison.cpp
So, am I doing anything outside the c++11 standard with this code or there is something wrong in both compilers?.
Note that If I remove the g++ problematic lines but leave the clang++ problematic one, the code compiles and works with g++ and if I remove the clang++ problematic line and leave the g++ problematic ones, the code compiles and works ok with clang++
Note also that I'm using the two templated structs to force the compiler to resolve the functions at compile time.
Thank you for your time and experience.
Update:
GCC chokes on your function stringlength. Try this:
constexpr size_t stringlength(char const* str, size_t i=0)
{
return str ? (str[i] ? 1 + stringlength(str, i+1) : 0) : 0;
}
To GCC 4.6.3 this seems dubious:
static constexpr int const* c = &a[0];
static constexpr int const* d = &b[0];
Try this:
static constexpr int* c = &a[0];
static constexpr int* d = &b[0];
Old answer:
You code seems to be correct and with GCC 4.6.3 it also compiles.
int main()
{
const char* a = "hallo";
const char* b = "qallo";
std::cout << is_equal(a,b,5) << std::endl;
constexpr const char* c = "hallo";
std::cout << is_equal(a,c,5) << std::endl;
}
Be careful, that the strings you are giving to your functions are constants.
See here what is allowed with constexpr.
Your arraylength example that you say doesn't work with GCC, works just fine with GCC 4.7 and 4.8, and except for an unrelated error about constexpr const, also with GCC 4.6.
As for your stringlength example: this is a limitation of GCC. I know I've seen a bug report about it already. You can work around it by rewriting your stringlength function:
constexpr size_t stringlength(char const* str, size_t len=0)
{
return str ? (str[len] ? stringlength(str, len + 1) : len) : 0;
}
but as far as I can tell, what you had already was perfectly valid.