C ++ pow异常类型转换 [英] C++ pow unusual type conversion

查看:429
本文介绍了C ++ pow异常类型转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我直接输出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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆