当我直接输出std :: pow(10,2)时,我得到100(做长)(pow(10,2))得到99.有人可以解释一下吗?
cout<<pow(10,2)<<endl;
cout<<(long)(pow(10,2))<<endl;
代码基本上是在主函数中。
使用CodeBlocks编译器是mingw32-g ++。exe -std = c ++ 11 Windows 8.1如果有帮助
答案 0 :(得分:2)
浮点数是近似值。偶尔你会得到一个可以准确表示的数字,但不要指望它。 100应该是可表示的,但在这种情况下它不是。有些东西注入了近似值,并为每个人毁了它。
当从浮点类型转换为整数时,整数不能保存任何小数值,因此会毫不客气地删除它们。没有隐式舍入,分数被丢弃。 99.9在99之后转换为99. 99,有9百万9。
因此,在从浮点类型转换为整数之前,将数字四舍五入,然后转换。除非丢弃分数 你想做什么。
cout
和大多数输出例程,在打印之前礼貌地和静默地舍入浮点值,所以如果有一点近似值,用户就不会对它感到困扰。
这种不精确性也是您不应直接比较浮点值的原因。 X可能不完全是pi,但它可能足够接近您的计算,因此您可以使用epsilon(一个软糖因子)进行比较,以判断您是否足够接近。
我觉得有趣,并且花了很多时间试图理清,如果不是using namespace std;
,就不会看到这个问题。
(long)pow(10,2)
提供100的预期结果。(long)std::pow(10,2)
没有。 pow
和std::pow
采用的路径从10,2到100之间存在一些差异会导致略有不同的结果。通过将整个std
命名空间拉入其文件中,OP意外地将自己射入了脚中。
为什么?
在文件的顶部我们有using namespace std;
这意味着编译器在查找double pow(double, double)
重载时不仅仅考虑pow
,还可以调用std::pow
和std::pow
是一个漂亮的小模板,确保在使用除float和double之外的数据类型进行调用时,正在进行正确的转换并且所有内容都是相同的类型。
(long)(pow(10,2))
不匹配
double pow(double, double)
以及它与
的模板实例化相匹配double std::pow(int, int)
哪个,我可以告诉解析到
附近return pow(double(10), double(2));
经过一些模板伏都教之后。
之间有什么区别
pow(double(10), double(2))
和
pow(10, 2)
在int
的调用中隐含从double
到pow
的转换是,我不知道。打电话给语言律师,因为这是微妙的。
如果这纯粹是一个舍入问题,那么
auto tempa = std::pow(10, 2);
应该是易受攻击的,因为tempa应该正是std::pow
返回的
cout << tempa << endl;
cout << (long) tempa << endl;
,输出应为
100
99
我得到了
100
100
因此,立即将std::pow(10, 2)
的回复转换为long
与存储然后转换不同。奇怪的。 auto tempa
并不完全是std::pow
返回的内容,或者其他内容对我来说太深了。
答案 1 :(得分:0)
这些是std :: pow重载:
float pow( float base, float exp );
double pow( double base, double exp );
long double pow( long double base, long double exp );
float pow( float base, int iexp );//(until C++11)
double pow( double base, int iexp );//(until C++11)
long double pow( long double base, int iexp ); //(until C++11)
Promoted pow( Arithmetic1 base, Arithmetic2 exp ); //(since C++11)
但是你的奇怪行为是MINGW关于双重存储的奇怪之处以及Windows运行时如何不喜欢它。我假设Windows看到的是99.9999这样的东西,当它被转换为整体类型时,它会占据一席之地。
int a = 3/2; // a is = 1
mingw使用Microsoft C运行时库,它们的printf实现不支持'long double'类型。作为解决方法,你可以强制转换为'double'并将其传递给printf。 因此,您需要双倍双倍:
在x86架构上,大多数C编译器实现long double作为x86硬件支持的80位扩展精度类型(有时存储为12或16字节以保持数据结构对齐),如C99 / C11标准中所规定的( IEC 60559浮点运算(附件F))。一个例外是用于x86的Microsoft Visual C ++,它使long double成为double的同义词。[2] Microsoft Windows上的英特尔C ++编译器支持扩展精度,但需要/ Qlong-double开关用于long double,以对应硬件的扩展精度格式。[3]