对于printf函数%.2f的疑惑

醉花阴柳 2015-10-24 02:34:58
我用printf把2.345按%.2f格式输出,结果是四舍五入后保留两位小数的,但是我把2.00345e2按同样格式输出却只是输出200.34并没有四舍五入。网上搜了下发现没这方面的问题啊,这个原因是什么呢?
...全文
1455 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
paschen 2015-10-26
  • 打赏
  • 举报
回复
楼上快说说了,是由于浮点数表示不精确 如果楼主想精确转换,可以使用如下方法;

double round(double d,unsigned p = 0) //d为原浮点数, p为精确位数
{
	if(d==0)
		return 0;
	double n=0.01;
	for(unsigned tmp=p;tmp>0;tmp--)
		n/=10;
	if(d>0)
		d+=n;
	else
		d-=n;
	//先转成字符串
	char chs[10],data[200];
	sprintf(chs,"%%.%uf",p);
	sprintf(data,chs,d);
	//再转成double
	return atof(data);
}
赵4老师 2015-10-26
  • 打赏
  • 举报
回复
醉花阴柳 2015-10-25
  • 打赏
  • 举报
回复
引用 10 楼 fefe82的回复:
[quote=引用 7 楼 qq_29120981 的回复:] [quote=引用 6 楼 wang0635的回复:][quote=引用 5 楼 qq_29120981 的回复:] [quote=引用 4 楼 wang0635的回复:][quote=引用 3 楼 qq_29120981 的回复:] [quote=引用 1 楼 dustpg的回复:]2.00345e2作为double实际上是200.3449999999989, 所以四舍五入会失败
2.345也是double型啊...[/quote] 2.345变成二进制是无限小数,而计算机只能保存有限位,所以实际上存成了跟它最接近的那个有限小数了[/quote] 2.345和2.00345e2保存的方法不同?一个是略大一个是略小?这个行为是无法预测的全看编译器实现吗?[/quote] 要看浮点数用的什么编码。二进制中只有分母是2的幂的分数才能是有限小数,而编码只能针对有限位的。几乎所有的浮点数都不准确,因为表示的范围太大,含有无穷多个数,而只有有限个数是准确的[/quote] 我还是没弄明白之前的问题,2.345存储略大2.00345e2存储略小,它们不都是double?[/quote] 内存中存储的二进制数,不是十进制数。 一般来说,double 使用的浮点数。 浮点数一般是用 1.xxx * 2^yyyy 的形式表示的。xxxx 的二进制位数一般是固定的。 这就是说,虽然他们的十进制小数部分都是 .345 ,但是他们浮点数表示的 1.xxxx 的部分很不相同。xxxx 的最后以为对应的十进制的值也不相同(因为 yyyy 是不同的)。 ===================== 那十进制打个比方吧。十进制浮点小数假设为 x.xxxx * 10 ^ yyyy 的形式。 于是 2.345 表示为 2.3450 * 10 ^ 0000 100.345 表示为 1.0034 * 10 ^ 0002 (只有四位小数可用,剩余的被丢弃。[不确定 IEEE754 里怎么处理的,这里假设为丢弃]) 于是当你均以两位小数输出的时候,前者会变成 2.35, 后者是 100.34 。[/quote] 嗯,谢谢,我已经明白了
fefe82 2015-10-24
  • 打赏
  • 举报
回复
引用 7 楼 qq_29120981 的回复:
[quote=引用 6 楼 wang0635的回复:][quote=引用 5 楼 qq_29120981 的回复:] [quote=引用 4 楼 wang0635的回复:][quote=引用 3 楼 qq_29120981 的回复:] [quote=引用 1 楼 dustpg的回复:]2.00345e2作为double实际上是200.3449999999989, 所以四舍五入会失败
2.345也是double型啊...[/quote] 2.345变成二进制是无限小数,而计算机只能保存有限位,所以实际上存成了跟它最接近的那个有限小数了[/quote] 2.345和2.00345e2保存的方法不同?一个是略大一个是略小?这个行为是无法预测的全看编译器实现吗?[/quote] 要看浮点数用的什么编码。二进制中只有分母是2的幂的分数才能是有限小数,而编码只能针对有限位的。几乎所有的浮点数都不准确,因为表示的范围太大,含有无穷多个数,而只有有限个数是准确的[/quote] 我还是没弄明白之前的问题,2.345存储略大2.00345e2存储略小,它们不都是double?[/quote] 内存中存储的二进制数,不是十进制数。 一般来说,double 使用的浮点数。 浮点数一般是用 1.xxx * 2^yyyy 的形式表示的。xxxx 的二进制位数一般是固定的。 这就是说,虽然他们的十进制小数部分都是 .345 ,但是他们浮点数表示的 1.xxxx 的部分很不相同。xxxx 的最后以为对应的十进制的值也不相同(因为 yyyy 是不同的)。 ===================== 那十进制打个比方吧。十进制浮点小数假设为 x.xxxx * 10 ^ yyyy 的形式。 于是 2.345 表示为 2.3450 * 10 ^ 0000 100.345 表示为 1.0034 * 10 ^ 0002 (只有四位小数可用,剩余的被丢弃。[不确定 IEEE754 里怎么处理的,这里假设为丢弃]) 于是当你均以两位小数输出的时候,前者会变成 2.35, 后者是 100.34 。
醉花阴柳 2015-10-24
  • 打赏
  • 举报
回复
引用 8 楼 wang0635的回复:
[quote=引用 7 楼 qq_29120981 的回复:] [quote=引用 6 楼 wang0635的回复:][quote=引用 5 楼 qq_29120981 的回复:] [quote=引用 4 楼 wang0635的回复:][quote=引用 3 楼 qq_29120981 的回复:] [quote=引用 1 楼 dustpg的回复:]2.00345e2作为double实际上是200.3449999999989, 所以四舍五入会失败
2.345也是double型啊...[/quote] 2.345变成二进制是无限小数,而计算机只能保存有限位,所以实际上存成了跟它最接近的那个有限小数了[/quote] 2.345和2.00345e2保存的方法不同?一个是略大一个是略小?这个行为是无法预测的全看编译器实现吗?[/quote] 要看浮点数用的什么编码。二进制中只有分母是2的幂的分数才能是有限小数,而编码只能针对有限位的。几乎所有的浮点数都不准确,因为表示的范围太大,含有无穷多个数,而只有有限个数是准确的[/quote] 我还是没弄明白之前的问题,2.345存储略大2.00345e2存储略小,它们不都是double?[/quote] 比如,十进制中,如果只能保存2位小数,那么区间 [2.345, 2.355) 中的所有数都只能用 2.35 表示[/quote] 虽然还是有些不明白,但还是谢谢大家了
wang0635 2015-10-24
  • 打赏
  • 举报
回复
引用 7 楼 qq_29120981 的回复:
[quote=引用 6 楼 wang0635的回复:][quote=引用 5 楼 qq_29120981 的回复:] [quote=引用 4 楼 wang0635的回复:][quote=引用 3 楼 qq_29120981 的回复:] [quote=引用 1 楼 dustpg的回复:]2.00345e2作为double实际上是200.3449999999989, 所以四舍五入会失败
2.345也是double型啊...[/quote] 2.345变成二进制是无限小数,而计算机只能保存有限位,所以实际上存成了跟它最接近的那个有限小数了[/quote] 2.345和2.00345e2保存的方法不同?一个是略大一个是略小?这个行为是无法预测的全看编译器实现吗?[/quote] 要看浮点数用的什么编码。二进制中只有分母是2的幂的分数才能是有限小数,而编码只能针对有限位的。几乎所有的浮点数都不准确,因为表示的范围太大,含有无穷多个数,而只有有限个数是准确的[/quote] 我还是没弄明白之前的问题,2.345存储略大2.00345e2存储略小,它们不都是double?[/quote] 比如,十进制中,如果只能保存2位小数,那么区间 [2.345, 2.355) 中的所有数都只能用 2.35 表示
醉花阴柳 2015-10-24
  • 打赏
  • 举报
回复
引用 6 楼 wang0635的回复:
[quote=引用 5 楼 qq_29120981 的回复:] [quote=引用 4 楼 wang0635的回复:][quote=引用 3 楼 qq_29120981 的回复:] [quote=引用 1 楼 dustpg的回复:]2.00345e2作为double实际上是200.3449999999989, 所以四舍五入会失败
2.345也是double型啊...[/quote] 2.345变成二进制是无限小数,而计算机只能保存有限位,所以实际上存成了跟它最接近的那个有限小数了[/quote] 2.345和2.00345e2保存的方法不同?一个是略大一个是略小?这个行为是无法预测的全看编译器实现吗?[/quote] 要看浮点数用的什么编码。二进制中只有分母是2的幂的分数才能是有限小数,而编码只能针对有限位的。几乎所有的浮点数都不准确,因为表示的范围太大,含有无穷多个数,而只有有限个数是准确的[/quote] 我还是没弄明白之前的问题,2.345存储略大2.00345e2存储略小,它们不都是double?
wang0635 2015-10-24
  • 打赏
  • 举报
回复
引用 5 楼 qq_29120981 的回复:
[quote=引用 4 楼 wang0635的回复:][quote=引用 3 楼 qq_29120981 的回复:] [quote=引用 1 楼 dustpg的回复:]2.00345e2作为double实际上是200.3449999999989, 所以四舍五入会失败
2.345也是double型啊...[/quote] 2.345变成二进制是无限小数,而计算机只能保存有限位,所以实际上存成了跟它最接近的那个有限小数了[/quote] 2.345和2.00345e2保存的方法不同?一个是略大一个是略小?这个行为是无法预测的全看编译器实现吗?[/quote] 要看浮点数用的什么编码。二进制中只有分母是2的幂的分数才能是有限小数,而编码只能针对有限位的。几乎所有的浮点数都不准确,因为表示的范围太大,含有无穷多个数,而只有有限个数是准确的
醉花阴柳 2015-10-24
  • 打赏
  • 举报
回复
引用 4 楼 wang0635的回复:
[quote=引用 3 楼 qq_29120981 的回复:] [quote=引用 1 楼 dustpg的回复:]2.00345e2作为double实际上是200.3449999999989, 所以四舍五入会失败
2.345也是double型啊...[/quote] 2.345变成二进制是无限小数,而计算机只能保存有限位,所以实际上存成了跟它最接近的那个有限小数了[/quote] 2.345和2.00345e2保存的方法不同?一个是略大一个是略小?这个行为是无法预测的全看编译器实现吗?
wang0635 2015-10-24
  • 打赏
  • 举报
回复
引用 3 楼 qq_29120981 的回复:
[quote=引用 1 楼 dustpg的回复:]2.00345e2作为double实际上是200.3449999999989, 所以四舍五入会失败
2.345也是double型啊...[/quote] 2.345变成二进制是无限小数,而计算机只能保存有限位,所以实际上存成了跟它最接近的那个有限小数了
醉花阴柳 2015-10-24
  • 打赏
  • 举报
回复
引用 1 楼 dustpg的回复:
2.00345e2作为double实际上是200.3449999999989, 所以四舍五入会失败
2.345也是double型啊...
wang0635 2015-10-24
  • 打赏
  • 举报
回复
几乎所有的浮点数都不准确
dustpg 2015-10-24
  • 打赏
  • 举报
回复
2.00345e2作为double实际上是200.3449999999989, 所以四舍五入会失败

70,038

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧