在我的非托管C++源代码中,我有:
#define _USE_MATH_DEFINES
#include <cmath>
Run Code Online (Sandbox Code Playgroud)
然后我使用M_PI几次.在Debug配置中进行编译可以完美地工作,但在Release中它给出了:
错误C2065:'M_PI':未声明的标识符
可能是导致此问题的配置属性是什么?
通过使用Boost数字常量,我可以获得什么(我猜在类型安全性,性能和准确性方面),例如pi<T>,在编译期间定义<boost/math/constants/constants.hpp>而不是包含<cmath>和替代使用M_PI,而不是更温暖的计算机:)?
TR1 在 C++11 中引入的许多新函数都具有丑陋的类似 C 的签名。例如,引用Boost的TR1文档(http://www.boost.org/doc/libs/1_52_0/doc/html/boost_tr1/subject_list.html#boost_tr1.subject_list.special):
// [5.2.1.1] associated Laguerre polynomials:
double assoc_laguerre(unsigned n, unsigned m, double x);
float assoc_laguerref(unsigned n, unsigned m, float x);
long double assoc_laguerrel(unsigned n, unsigned m, long double x);
Run Code Online (Sandbox Code Playgroud)
显然,人们更喜欢某种模板化实现(这实际上是 Boost 中这些函数的“本机”签名),或者至少是某种重载而不是多个标识符。
我可以理解,以 C 兼容性为目标意味着支持这些标识符,但这对于纯 C++ 使用者来说是一个麻烦。除了 之外<cmath>,还可能有一些<math>具有更自然界面的 。
我缺少什么(除了可能之前提出的一些问题)?
我有以下名为test.cpp的C++测试程序:
#include <cmath>
#include <iostream>
double sqrt(double d) { return std::sqrt(d); }
int main()
{
std::cout << "sqrt(4): " << sqrt(4) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
这是一些非常人为的代码,你可能已经猜到我只是想用Stroustrup做一个练习.他宣称双sqrt(双),并希望读者定义它.
我使用g ++ 4.8(来自Qt 5.1的MINGW版本)编译了上面的代码:
C:\Windows\Temp>g++ -o test.exe -g test.cpp
Run Code Online (Sandbox Code Playgroud)
当我运行生成的可执行文件时,Windows 7说"test.exe已停止工作".
要查看出了什么问题,我在GNU调试器中运行了test.exe.调试器命令和输出:
C:\Windows\Temp>gdb -q test.exe
Reading symbols from C:\Windows\Temp\test.exe...done.
(gdb) b main
Breakpoint 1 at 0x401625: file test.cpp, line 8.
(gdb) run
Starting program: C:\Windows\Temp\test.exe
[New Thread 12080.0x2ba0]
Breakpoint 1, main () at test.cpp:8
8 std::cout << "sqrt(4): " << sqrt(4) << std::endl;
(gdb) s …Run Code Online (Sandbox Code Playgroud) 给定以下用户定义类型S并将转换函数加倍:
struct S
{
operator double() { return 1.0;}
};
Run Code Online (Sandbox Code Playgroud)
以及使用以下类型调用cmath函数S:
#include <cmath>
void test(S s) {
std::sqrt(s);
std::log(s);
std::isgreater(s,1.0);
std::isless(s,1.0);
std::isfinite(s) ;
}
Run Code Online (Sandbox Code Playgroud)
此代码编译与gcc使用libstdc++(见直播),但clang利用libc++它生成了几个调用(误差在现场观看),出现以下错误的isgreater:
error: no matching function for call to 'isgreater'
std::isgreater(s,1.0);
^~~~~~~~~~~~~~
note: candidate template ignored: disabled by 'enable_if' [with _A1 = S, _A2 = double]
std::is_arithmetic<_A1>::value &&
^
Run Code Online (Sandbox Code Playgroud)
我想在编译时为给定范围内的数学函数计算查找表,然后在运行时从表中检索值.我的代码如下:
#include <iostream>
#include <cmath>
template<int size>
class LookupTable {
public:
constexpr LookupTable(double xMin, double xMax) : array(), xMin(xMin), xMax(xMax), dx((xMax - xMin) / (size - 1)) {
for(auto i = 0; i < size; ++i)
array[i] = exp(xMin + i * dx);
}
constexpr double operator()(double x) const {
return array[std::min(std::max(static_cast<int>((x - xMin) / dx), 0), size-1)];
}
private:
double array[size];
double xMin;
double xMax;
double dx;
};
int main() {
const double x = 0.5;
constexpr LookupTable<10000> table(0.0, …Run Code Online (Sandbox Code Playgroud) 我得到了一个名为变量y0并包含cmath的变量,在g++不带任何参数的情况下进行编译时,出现编译错误
error: invalid operands of types ‘double(double) throw ()’ and ‘double’ to binary ‘operator+’
y = y0 + R;
~~~^~~
为了进行实验,我删除了cmath,其中包括所有内容,一切正常。
#include <iostream>
#include <cmath>
double y0, y, R;
int main() {
std::cin >> y0 >> R;
y = y0 + R;
}
Run Code Online (Sandbox Code Playgroud) 我想从 C++ 标准的角度(GCC 9.3、C++20)了解以下代码的行为:
#include <cstdlib>
template<class> struct type_tester;
int main() {
type_tester<decltype(abs(0.1))>{}; // int abs(int) overload is selected for some reason!
type_tester<decltype(std::abs(0.1))> {}; // double abs(double) overload is selected, as one would expect
}
Run Code Online (Sandbox Code Playgroud)
所以,int abs(int)是导入到全局命名空间,而double abs(double)不是!
为什么?
是否有任何C++ 11 constexpr常量可用于代替常量宏<cmath>,即常量M_PI和朋友?或者缺少那些const在运行时提供这些常量的全局值?
这是一个由两部分组成的问题:
如果我#include <cmath>在标题中, 1 - 使用,比如说,和
之间有什么区别?
2 - 为什么我得到的汇编代码与另一个的汇编代码如此不同?(产生的指令明显减少)std::log10()log10()std::log10()
谢谢!
#include <cmath>
float using_std(float i) {
return std::log10(i);
}
float not_using_std(float i) {
return log10(i);
}
Run Code Online (Sandbox Code Playgroud)
组装(来自godbolt)
using_std(float):
jmp log10f
not_using_std(float):
sub rsp, 8
cvtss2sd xmm0, xmm0
call log10
add rsp, 8
cvtsd2ss xmm0, xmm0
ret
Run Code Online (Sandbox Code Playgroud)
我知道这些指令不是“实际”汇编,它们可能隐藏了更细粒度的指令,我只是想知道我看到的差异是否与代码的实际性能相关。
好吧,这是有道理的,如果我改为#include <math.h>,它们是相同的:
using_std(float):
jmp log10f
not_using_std(float):
jmp log10f
Run Code Online (Sandbox Code Playgroud)