解题思路:
这道题的难点是怎么查询小数点后的位数,最简单的做法是将浮点数转换成字符串,查找到小数点后就可以找到小数点n位后的那个值了,c++里的string库里提供了浮点数转字符串的to_string函数,不过这个函数只能保存小数点后六位有效数字,对于需要很多位的就失效了。
在c/c++里还有一个sprintf函数,具体用法如下:
C 库函数 - sprintf()
C 标准库 - <stdio.h>
描述
C 库函数 int sprintf(char *str, const char *format, ...) 发送格式化输出到 str 所指向的字符串。
声明
下面是 sprintf() 函数的声明。
int sprintf(char *str, const char *format, ...)
参数
str -- 这是指向一个字符数组的指针,该数组存储了 C 字符串。
format -- 这是字符串,包含了要被写入到字符串 str 的文本。它可以包含嵌入的 format 标签,format 标签可被随后的附加参数中指定的值替换,并按需求进行格式化。format 标签属性是 %[flags][width][.precision][length]specifier,
附加参数 -- 根据不同的 format 字符串,函数可能需要一系列的附加参数,每个参数包含了一个要被插入的值,替换了 format 参数中指定的每个 % 标签。参数的个数应与 % 标签的个数相同。
返回值
如果成功,则返回写入的字符总数,不包括字符串追加在字符串末尾的空字符。如果失败,则返回一个负数。
例如d=16.995
char p[100];
sprintf(p,"%.5lf",d);
这时候,打印字符数组p为16.99500,p[2]的值是'.',p[3]的值是'9',注意:这里都是字符格式。
也就是说,我们可以将一个浮点数或者整数或者字符等等,通过格式控制,原样的复制到一个字符数组中。
这个方法c语言同样适用。
不过因为是字符数组而不是string字符串类型,所以我们需要自己实现查找函数,查找到小数点,就能找到小数点后n位的那个数了。
参考代码:
#include <iostream> #include <cstring> #include <cmath> using namespace std; int find(char *p,char x){ int k=0; while(*p!=x){ p++; k++; } return k; } int main() { int a,b,n; cin>>a>>b>>n; char p[200]; sprintf(p,"%.100lf",(double)a/b);//小数点后保留一百位 cout<<p[find(p,'.')+n];//查找小数点的位置,再+n // string str = to_string(a/b);//只能保存六位小数 //// cout<<a/b<<" "<<str<<endl; // cout<<str[str.find('.')+n]; return 0; }
在c语言的stdlib.h库里还有ecvt和fcvt函数,也可以将浮点数转换为字符串,具体解释如下:
函数名:ecvt
头文件:<stdlib.h>
函数原型: char *ecvt(double f,int n,int *p,int *c);
功能:把浮点数转换为字符串
参数:double f 要转换的浮点数
int n 显示的位数
int *p 一个指向变量返回数值的小数点的地址的指针
int *c 表示数值正负的指针
返回值:返回字符串指针
不过经过几次尝试,可能因为编译环境的原因,在网站里字符串里并没有一百多位,无法通过本题,不过gcc的编译环境是可以的。
注意:这里转换的字符串中没有小数点,不过第三个参数可以得到小数点本来在的那个位置,如13.1415会转为131415,第三参数就得到了小数点的位置2。
#include <stdio.h> #include <stdlib.h> int main() { int a,b,n; scanf("%d%d%d",&a,&b,&n); char *p = ecvt((double)a/b,100,&a,&b); // printf("%s\n",p); printf("%c",*(p+a+n-1)); return 0; }
还有一个做法是将小数*(10^n),把小数放大,然后个位的值即为小数点后n位的值。
例如3.1415,要得到小数点后4位的这个5,就让3.1415*(10^4)=31415,然后31415%10=5,这样就把这个5取到了。
不过因为精度问题,只有long double这个类型才能实现小数点后一百多位的精度。
因为只能使用long double类型,浮点数是不能直接%取余的,需要借助math数学库函数里的fmod函数进行浮点数取余。
因为fmod会将小数点后的值也会返回,所以我们要舍去小数点后的值,转成int可以直接舍去,使用下取整函数trunc函数也可以。
以上。
#include <iostream> #include <cstring> #include <cmath> using namespace std; int main() { long double a,b,n; cin>>a>>b>>n; n=pow(10,n); long double x=a*n/b; int k=fmod(x,10); cout<<k; //cout<<trunc(fmod(x,10)); return 0; }
0.0分
162 人评分
C语言训练-计算:t=1-1/(2*2)-1/(3*3)-...-1/(m*m) (C语言代码)浏览:799 |
C语言程序设计教程(第三版)课后习题6.9 (C语言代码)浏览:1052 |
2005年春浙江省计算机等级考试二级C 编程题(2) (C语言代码)浏览:672 |
C语言程序设计教程(第三版)课后习题8.4 (C语言代码)浏览:628 |
1009题解浏览:802 |
Quadratic Equation (C语言代码)浏览:1034 |
神奇的fans (C语言代码)浏览:1124 |
班级人数 (C语言代码)浏览:980 |
C语言程序设计教程(第三版)课后习题8.6 (C语言代码)浏览:594 |
1392题解(大数相加)浏览:640 |