C++中输出设置有效位和计算机中浮点数的保存问题
2013-09-24 22:46
393 查看
Google Code Jam上的第二题是“Captain Hammer”问题。
具体描述如下:
who needs them when the fuselage is made of a special Wonderflonium isotope that makes it impervious to harm.
Piloting the Hamjet is a not a job for your typical, meek-bodied superhero. That's why the Hamjet belongs to Captain Hammer, who is himself impervious to harm. The G-forces that the pilot endures when
taking a trip in the Hamjet are legen-dary.
The Hamjet takes off at an angle of θ degrees up and a speed of V meters per second. Vis a fixed value that is determined by the awesome power of the Hamjet engine and
the capacity of its fuel tank. The destination is D meters away. Your job is to program the Hamjet's computer to calculate θ given V and D.
Fortunately, the Hamjet's Wondeflonium hull is impervious to air friction. Even more fortunately, the Hamjet doesn't fly too far or too high, so you can assume that the Earth is flat, and that the acceleration
due to gravity is a constant 9.8 m/s2 down.
smallest positive one.
An answer will be considered correct if it is within 10-6 of the exact answer, in absolute or relative error. See the FAQ for
an explanation of what that means, and what formats of floating-point numbers we accept.
1 ≤ V ≤ 300;
1 ≤ D ≤ 10000;
It is guaranteed that each test case will be solvable.
这道题乍看起来,好像挺简单的,是一个简单的高中物理题,但是其实坑还蛮多的,试验了好多次(囧)。
首先,有精度问题需要考虑,C++中如何设置输出数据的精度,不是经常接触到的,还需要查看一些文档。
具体的设置方法为:
其中,setf表示要设置cout的一些format flag(具体参考http://www.cplusplus.com/reference/ios/ios_base/setf/),这里我们只需要开启固定精度,然后就利用precision方法设置精度为7位,最后将刚刚设定的format flag复位。如果不先利用setf置位,precision是不起作用的!
还有就是由于计算机中浮点数保存的时候是不一定就是浮点本身(有一个近似,因为转换为2进制时,有可能是无限循环小数),例如1.2在计算机中保存的就是1.19999999999999995559,1445*9.8/(119*119)得到的结果就是“1.00000000000000022204”(9.8保存的是9.80000000000000071054)。这就会导致“0有可能不是0”,而是一个非常接近0的小数(可能为正,可能为负)。一般情况下,没什么问题,但是对一些特殊的运算,例如取平方根,“负0”就可能会导致结果为“-nan”。这道题中给出的测试用例中就会出现这样的问题,所以在取平方根时要判断是不是“负0”的情况。
具体代码如下:
具体描述如下:
Problem
The Hamjet is a true marvel of aircraft engineering. It is a jet airplane with a single engine so powerful that it burns all of its fuel instantly during takeoff. The Hamjet doesn't have any wings becausewho needs them when the fuselage is made of a special Wonderflonium isotope that makes it impervious to harm.
Piloting the Hamjet is a not a job for your typical, meek-bodied superhero. That's why the Hamjet belongs to Captain Hammer, who is himself impervious to harm. The G-forces that the pilot endures when
taking a trip in the Hamjet are legen-dary.
The Hamjet takes off at an angle of θ degrees up and a speed of V meters per second. Vis a fixed value that is determined by the awesome power of the Hamjet engine and
the capacity of its fuel tank. The destination is D meters away. Your job is to program the Hamjet's computer to calculate θ given V and D.
Fortunately, the Hamjet's Wondeflonium hull is impervious to air friction. Even more fortunately, the Hamjet doesn't fly too far or too high, so you can assume that the Earth is flat, and that the acceleration
due to gravity is a constant 9.8 m/s2 down.
Input
The first line of the input gives the number of test cases, T. T lines follow. Each line will contain two positive integers -- V and D.Output
For each test case, output one line containing "Case #x: θ", where x is the case number (starting from 1) and θ is in degrees up from the the horizontal. If there are several possible answers, output thesmallest positive one.
An answer will be considered correct if it is within 10-6 of the exact answer, in absolute or relative error. See the FAQ for
an explanation of what that means, and what formats of floating-point numbers we accept.
Limits
1 ≤ T ≤ 4500;1 ≤ V ≤ 300;
1 ≤ D ≤ 10000;
It is guaranteed that each test case will be solvable.
Sample
这道题乍看起来,好像挺简单的,是一个简单的高中物理题,但是其实坑还蛮多的,试验了好多次(囧)。
首先,有精度问题需要考虑,C++中如何设置输出数据的精度,不是经常接触到的,还需要查看一些文档。
具体的设置方法为:
cout.setf(ios::fixed); cout.precision(7); cout << theta2 << endl; cout.unsetf(ios::fixed);
其中,setf表示要设置cout的一些format flag(具体参考http://www.cplusplus.com/reference/ios/ios_base/setf/),这里我们只需要开启固定精度,然后就利用precision方法设置精度为7位,最后将刚刚设定的format flag复位。如果不先利用setf置位,precision是不起作用的!
还有就是由于计算机中浮点数保存的时候是不一定就是浮点本身(有一个近似,因为转换为2进制时,有可能是无限循环小数),例如1.2在计算机中保存的就是1.19999999999999995559,1445*9.8/(119*119)得到的结果就是“1.00000000000000022204”(9.8保存的是9.80000000000000071054)。这就会导致“0有可能不是0”,而是一个非常接近0的小数(可能为正,可能为负)。一般情况下,没什么问题,但是对一些特殊的运算,例如取平方根,“负0”就可能会导致结果为“-nan”。这道题中给出的测试用例中就会出现这样的问题,所以在取平方根时要判断是不是“负0”的情况。
具体代码如下:
#include <iostream> #include <cmath> #include <cstdio> #include <cstdlib> using namespace std; #define PI 3.14159 int main() { int T = 0; cin >> T; double V = 0.0, D = 0.0; double g = 9.8; double theta1 = 0.0; double theta2 = 0.0; for(int i = 0; i < T; i++) { cin >> V >> D; double tmp = g*D/(V*V); // cout << "xxxxxxxxxxxx" << V << "\t" << D << "\t" << tmp << endl; double b = sqrt(1 + tmp); double ac = 0.0; if(1 - tmp < 1e-6 && 1 - tmp > -1e-6) { ac = 0.0; } else { ac = sqrt(1 - tmp); } theta1 = asin((b + ac)/2)*180.0/M_PI; theta2 = asin((b - ac)/2)*180.0/M_PI; // cout << "xxxxxxxxxxxx" << V << "\t" << D << "\t" << 1 - tmp << endl; if(theta1 > 0 && theta2 > 0) { if(theta1 > theta2) { cout << "Case #" << i + 1 << ": "; cout.setf(ios::fixed); cout.precision(7); cout << theta2 << endl; cout.unsetf(ios::fixed); } else { cout << "Case #" << i + 1 << ": "; cout.setf(ios::fixed); cout.precision(7); cout << theta1 << endl; cout.unsetf(ios::fixed); } } else { if(theta1 > theta2) { cout << "Case #" << i + 1 << ": "; cout.setf(ios::fixed); cout.precision(7); cout << theta1 << endl; cout.unsetf(ios::fixed); } else { cout << "Case #" << i + 1 << ": "; cout.setf(ios::fixed); cout.precision(7); cout << theta2 << endl; cout.unsetf(ios::fixed); } } } return 0; }
相关文章推荐
- Java网络编程:UDP通信
- 无线网络工具Inssider源代码
- LSP(Layered Service Provider )---子浏览器被劫持
- 网络编程select
- 网络通信—udp使用领悟
- 由ASP.NET所谓前台调用后台、后台调用前台想到HTTP——实践篇(二)
- java 常见数据结构
- JAVA网络编程:TCP通信
- 计算机视觉与模式识别 code
- 解析VMware网络设置的3种工作模式
- C#网络编程
- socket通讯和.net remoting实现网络数据通信哪个好些
- UNP读书笔记--Chapter 4 Elementary TCP Sockets
- 使用Google-Project-Hosting搭建自己的网络SVN服务器
- ZOJ Goldbach 2013年长沙赛区网络赛
- 深入理解HTTP Session
- 一个应届计算机毕业生的2012求职之路
- 我的中科院之旅
- 关于中缀转后缀表达式的树型算法
- C#实现通过HttpWebRequest发送POST请求实现网站自动登陆