C ++ pow异常类型转换 [英] C++ pow unusual type conversion
问题描述
当我直接输出std :: pow(10,2),我得到100,而做(长)(pow(10,2))给出99.有人解释这个请吗?
When I directly output std::pow(10,2), I get 100 while doing (long)(pow(10,2)) gives 99. Can someone explained this please ?
cout<<pow(10,2)<<endl;
cout<<(long)(pow(10,2))<<endl;
代码基本上是在main函数中。
The code is basically this in the main function.
编译器是mingw32-g ++。exe -std = c ++ 11使用CodeBlocks
Windows 8.1如果这有助于
The compiler is mingw32-g++.exe -std=c++11 using CodeBlocks Windows 8.1 if that helps
推荐答案
浮点数是近似值。偶尔,你得到一个可以准确表示的数字,但不要指望它。 100应该是可以表示的,但在这种情况下不是。
Floating point numbers are approximations. Occasionally you get a number that can be exactly represented, but don't count on it. 100 should be representable, but in this case it isn't. Something injected an approximation and ruined it for everybody.
当从浮点类型转换为整数时,整数不能保存任何小数值,所以它们不会被忽略掉。没有隐式四舍五入,分数被丢弃。 99.9转换为99. 99,在它是99之后有一百万9秒。
When converting from a floating point type to an integer, the integer cannot hold any fractional values so they are unceremoniously dropped. There is no implicit rounding off, the fraction is discarded. 99.9 converts to 99. 99 with a million 9s after it is 99.
因此,在从浮点类型转换为整数之前,舍入数字,然后转换。
So before converting from a floating point type to an integer, round the number, then convert. Unless discarding the fraction is what you want to do.
cout
,而且大多数输出例程,打印之前的礼貌和静默的浮点值,所以如果有一个近似的位,用户不打扰它。
cout
, and most output routines, politely and silently round floating point values before printing, so if there is a bit of an approximation the user isn't bothered with it.
这个不精确也是为什么你不应该直接比较浮点值。 X可能不是完全pi,但它可能足够接近你的计算,所以你执行与ε的比较,一个fudge因子,以告诉你是否足够接近。
This inexactness is also why you shouldn't directly compare floating point values. X probably isn't exactly pi, but it might be close enough for your computations, so you perform the comparison with an epsilon, a fudge factor, to tell if you are close enough.
我觉得有趣,并且烧了很多时间试图整理出来,如果不是使用命名空间std;
,就不会看到这个问题。
What I find amusing, and burned a lot of time trying to sort out, is would not have even seen this problem if not for using namespace std;
.
(长)pow(10,2)
提供预期结果100. (long)std :: pow(10,2)
不会。通过 pow
和 std :: pow
采用的从10,2到100的路径中的一些差异导致稍微不同的结果。通过将整个 std
命名空间拖到他们的文件中,OP偶然在脚下自拍。
(long)pow(10,2)
provides the expected result of 100. (long)std::pow(10,2)
does not. Some difference in the path from 10,2 to 100 taken by pow
and std::pow
results in slightly different results. By pulling the entire std
namespace into their file, OP accidentally shot themselves in the foot.
为什么?
在文件顶部我们有命名空间std;
这意味着编译器不只是考虑 double pow(double,double)
code>重载,它也可以调用 std :: pow
和 std :: pow
是一个漂亮的小模板确保当使用float和double以外的数据类型调用时,正确的转换正在进行,一切都是相同类型。
Up at the top of the file we have using namespace std;
this means the compiler is not just considering double pow(double, double)
when looking for pow
overloads, it can also call std::pow
and std::pow
is a nifty little template making sure that when called with datatypes other than float and double the right conversions are taking place and everything is the same type.
(long)(pow(10,2))
不匹配
double pow(double, double)
以及它匹配
double std::pow(int, int)
其中,我可以告诉我可以解析为
Which, near as I can tell resolves down to
return pow(double(10), double(2));
pow(double(10), double(2))
和
pow(10, 2)
调用 pow
时,code> int 到 double
不知道。
with an implied conversion from int
to double
on the call to pow
is, I do not know. Call in the language lawyers because it's something subtle.
如果这只是一个四舍五入问题,那么
If this is purely a rounding issue then
auto tempa = std::pow(10, 2);
应该是脆弱的,因为tempa应该是 std :: pow
返回
should be vulnerable because tempa should be exactly what std::pow
returns
cout << tempa << endl;
cout << (long) tempa << endl;
,输出应为
100
99
我得到
100
100
$ b b
因此,立即将 std :: pow(10,2)
的返回转换为 long
从存储然后铸造。奇怪的。 auto tempa
不是什么 std :: pow
返回或有其他事情对我来说太深。
So immediately casting the return of std::pow(10, 2)
into a long
is different from storing and then casting. Weird. auto tempa
is not exactly what std::pow
returns or there is something else going on that is too deep for me.
这篇关于C ++ pow异常类型转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!