指针原来是套娃的


私信TA

用户名:uq_92467646842

访问量:52318

签 名:

个人博客:blog.imtwa.top

等  级
排  名 11
经  验 26504
参赛次数 49
文章发表 128
年  龄 0
在职情况 学生
学  校
专  业 物联网工程

  自我简介:

解题思路:

这道题的难点是怎么查询小数点后的位数,最简单的做法是将浮点数转换成字符串,查找到小数点后就可以找到小数点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库里还有ecvtfcvt函数,也可以将浮点数转换为字符串,具体解释如下:

函数名: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 人评分

  评论区

  • «
  • »