我一直认为随机数在0和1之间,没有1
,即它们是来自半开区间[0,1]的数字.cppreference.com上的文件std::generate_canonical
证实了这一点.
但是,当我运行以下程序时:
#include <iostream>
#include <limits>
#include <random>
int main()
{
std::mt19937 rng;
std::seed_seq sequence{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
rng.seed(sequence);
rng.discard(12 * 629143 + 6);
float random = std::generate_canonical<float,
std::numeric_limits<float>::digits>(rng);
if (random == 1.0f)
{
std::cout << "Bug!\n";
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它给了我以下输出:
Bug!
Run Code Online (Sandbox Code Playgroud)
即它1
会让我产生完美,这会导致我的MC集成出现问题.是有效行为还是我身边有错误?这给出了与G ++ 4.7.3相同的输出
g++ -std=c++11 test.c && ./a.out
Run Code Online (Sandbox Code Playgroud)
和铿锵3.3
clang++ -stdlib=libc++ -std=c++11 test.c && ./a.out
Run Code Online (Sandbox Code Playgroud)
如果这是正确的行为,我该如何避免1
?
编辑1:来自git的G ++似乎遇到了同样的问题.我在 …
我最近收到一个关于程序无法使用-O3开关编译的错误报告(请参阅https://github.com/cschwan/sage-on-gentoo/issues/66).特别是,问题是编译在某个时刻挂起.通过使用-O2编译来解决这个问题(我很清楚使用-O3编译的程序可能会被破坏,但我不知道-O3可能会挂起编译器).如果要重现问题运行
wget http://perso.ens-lyon.fr/xavier.pujol/fplll/libfplll-3.0.12.tar.gz
tar -xf libfplll-3.0.12.tar.gz
cd libfplll-3.0.12
./configure CXXFLAGS="-O3"
make
Run Code Online (Sandbox Code Playgroud)
我想知道为什么-O3挂起编译器,所以我试图追查这个问题.首先,我试图找出-O3之间的-O2之间的差异.Gcc的手册页指出-O3启用-O2和以下的开关(让我们调用它们x
):
-finline-functions -funswitch-loops -fpredictive-commoning -fgcse-after-reload
-ftree-vectorize -fipa-cp-clone
Run Code Online (Sandbox Code Playgroud)
我验证通过时调用gcc的比较器的输出-Q -O2 --help=optimizers
和-Q -O3 --help=optimizers
.然后,我计划有选择地删除开关,以便找到导致问题的开关.但是,编译与-O2以及上面的附加开关一起工作正常,所以我总结道
-O3 != -O2 x
Run Code Online (Sandbox Code Playgroud)
现在我的问题是:有人知道-O2和-O3之间是否存在进一步的区别(未记录?),有没有人经历过类似的行为?这可能是编译器错误吗?
这似乎是一个非常简单的问题:如何删除第一个(第n个)类型std::tuple
?
例:
typedef std::tuple<int, short, double> tuple1;
typedef std::tuple<short, double> tuple2;
Run Code Online (Sandbox Code Playgroud)
上述操作将转变tuple1
为tuple2
.可能吗?
最近更新了GCC 4.8的文档,现在引入了一个新的优化开关-Og
.这个
[..]解决了快速编译和卓越调试体验的需求,同时提供了合理的运行时性能.总体开发经验应优于默认优化级别-O0.
此切换是否暗示-g
或我是否必须CXXFLAGS
手动将其添加到我的手中?
到目前为止,我在C++标准库中看到的所有其他内容都在std
命名空间中.如果我使用的东西std::chrono
我通常超过我的每行限制80个字符 - 这不是一个问题,只是不方便.
所以这里我的简单问题是:为什么chrono头有自己的命名空间?
在C++ 11中,我使用constexpr函数作为模板参数的默认值 - 它看起来像这样:
template <int value>
struct bar
{
static constexpr int get()
{
return value;
}
};
template <typename A, int value = A::get()>
struct foo
{
};
int main()
{
typedef foo<bar<0>> type;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
G ++ 4.5和4.7编译它,但Clang ++ 3.1没有.来自clang的错误消息是:
clang_test.cpp:10:35: error: non-type template argument is not a constant expression
template <typename A, int value = A::get()>
^~~~~~~~
clang_test.cpp:17:19: note: while checking a default template argument used here
typedef foo<bar<3>> type;
~~~~~~~~~^~
clang_test.cpp:10:35: note: undefined function …
Run Code Online (Sandbox Code Playgroud) 我目前正在编写一个C++模板表达式库,并将一些实例与程序集级别的手写代码进行比较.手写功能如下:
spinor multiply(vector const& a, vector const& b)
{
spinor result = {
a.at<1>() * b.at<1>() - a.at<2>() * b.at<2>()
- a.at<4>() * b.at<4>() - a.at<8>() * b.at<8>(),
a.at<1>() * b.at<2>() - a.at<2>() * b.at<1>(),
a.at<1>() * b.at<4>() - a.at<4>() * b.at<1>(),
a.at<1>() * b.at<8>() - a.at<8>() * b.at<1>(),
a.at<2>() * b.at<4>() - a.at<4>() * b.at<2>(),
a.at<2>() * b.at<8>() - a.at<8>() * b.at<2>(),
a.at<4>() * b.at<8>() - a.at<8>() * b.at<4>()
};
return result;
}
Run Code Online (Sandbox Code Playgroud)
的vector
类只是在四个双打的包装,其可以通过使用读出at<index>()
的成员函数.由于设计决策,四个组件的索引1, …
假设您有以下(格式错误的)程序:
struct A
{
A(int, int)
{
}
};
template <typename T>
class B
{
B()
{
if (sizeof (T) == 1)
{
throw A(0); // wrong, A() needs two arguments
}
}
};
int main()
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
GCC编译这个程序没有任何错误,clang ++拒绝它错误.
以下是问题的精简版:
#include <initializer_list>
#include <iostream>
enum objects { zero, one, two, three, four, five, six, seven };
std::initializer_list<objects> objects_list()
{
return { zero, one, two, three, four, five, six, seven };
}
int main()
{
for (auto a : objects_list())
{
std::cout << a << ' ';
}
std::cout << '\n';
}
Run Code Online (Sandbox Code Playgroud)
我的期望是方案产出:
0 1 2 3 4 5 6 7
Run Code Online (Sandbox Code Playgroud)
这是由GCC 4.9.2确认的,但GCC新鲜的GCC存储库产生:
0 0 -85997960 32712 -1076836160 32765 0 32
Run Code Online (Sandbox Code Playgroud)
这看起来基本上是随机数.
我的程序或GCC有问题吗?
在我的代码中,我经常计算类似下面的内容(这里为简单的C代码):
float cos_theta = /* some simple operations; no cosf call! */;
float sin_theta = sqrtf(1.0f - cos_theta * cos_theta); // Option 1
Run Code Online (Sandbox Code Playgroud)
对于此示例,请忽略由于不精确而导致平方根的参数可能为负.我通过额外的fdimf
电话修好了.但是,我想知道以下是否更精确:
float sin_theta = sqrtf((1.0f + cos_theta) * (1.0f - cos_theta)); // Option 2
Run Code Online (Sandbox Code Playgroud)
cos_theta
介于两者之间-1
,+1
因此对于每种选择都会有一些情况,我会减去相似的数字,因此会失去精度,对吧?什么是最精确的,为什么?
请考虑以下代码:
#include <type_traits>
#include <utility>
template <typename F>
class function
{
public:
// using function_type = typename std::decay<F>::type;
using function_type = F;
function(F func)
: function_(func)
{
}
private:
function_type function_;
};
template <typename F>
function<F> make_function(F&& func)
{
return function<F>(std::forward<F>(func));
}
double f1(double)
{
return 0.0;
}
template <typename T>
T f2(T)
{
return T();
}
int main()
{
// works in both cases
make_function(f1);
// needs decay (with CLANG)
make_function(f2<double>);
}
Run Code Online (Sandbox Code Playgroud)
该类function
旨在成为任何一个简单的包装器Callable
.代码用GCC编译好(我从git存储库测试了4.9.2和7.0.0 20160427).然而,clang(3.5.0)抱怨:
function.cpp:17:17: …
Run Code Online (Sandbox Code Playgroud) 我惊讶地看到这个程序的输出:
#include <iostream>
#include <random>
int main()
{
std::mt19937 rng1;
std::mt19937 rng2;
std::uniform_real_distribution<double> dist;
double random = dist(rng1);
rng2.discard(2);
std::cout << (rng1() - rng2()) << "\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
是0
- 即std::uniform_real_distribution
使用两个随机数来产生double
[0,1]范围内的随机值.我认为它只会生成一个并重新缩放.在考虑之后,我猜这是因为std::mt19937
产生32位整数并且double是这个大小的两倍,因此不是"足够随机".
问题:如何一般地找出这个数字,即随机数生成器和浮点类型是否是任意类型?
编辑:我只是注意到我可以使用std::generate_canonical
,因为我只对[0,1)的随机数感兴趣.不确定这是否有所作为.