user-0 提问: 对于printf函数%.2f的疑惑

回复:
user: user-1
content: 楼上快说说了，是由于浮点数表示不精确  如果楼主想精确转换，可以使用如下方法；   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); }

user: user-2
content: http://bbs.csdn.net/topics/390676437

user: user-0
content: 引用 10 楼 fefe82的回复:[quote=引用 7 楼 qq_29120981 的回复:] [quote=引用 6 楼 wang0635的回复:][quote=引用 5 楼 qq_29120981 的回复:] [quote=引用 4 楼 wang0635的回复:][quote=引用 3 楼 qq_29120981 的回复:] [quote=引用 1 楼 user-5的回复:]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] 嗯，谢谢，我已经明白了

user: user-3
content: 引用 7 楼 qq_29120981 的回复:[quote=引用 6 楼 wang0635的回复:][quote=引用 5 楼 qq_29120981 的回复:] [quote=引用 4 楼 wang0635的回复:][quote=引用 3 楼 qq_29120981 的回复:] [quote=引用 1 楼 user-5的回复:]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 。

user: user-0
content: 引用 8 楼 wang0635的回复:[quote=引用 7 楼 qq_29120981 的回复:] [quote=引用 6 楼 wang0635的回复:][quote=引用 5 楼 qq_29120981 的回复:] [quote=引用 4 楼 wang0635的回复:][quote=引用 3 楼 qq_29120981 的回复:] [quote=引用 1 楼 user-5的回复:]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] 虽然还是有些不明白，但还是谢谢大家了

user: user-4
content: 引用 7 楼 qq_29120981 的回复:[quote=引用 6 楼 wang0635的回复:][quote=引用 5 楼 qq_29120981 的回复:] [quote=引用 4 楼 wang0635的回复:][quote=引用 3 楼 qq_29120981 的回复:] [quote=引用 1 楼 user-5的回复:]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 表示

user: user-0
content: 引用 6 楼 wang0635的回复:[quote=引用 5 楼 qq_29120981 的回复:] [quote=引用 4 楼 wang0635的回复:][quote=引用 3 楼 qq_29120981 的回复:] [quote=引用 1 楼 user-5的回复:]2.00345e2作为double实际上是200.3449999999989, 所以四舍五入会失败 2.345也是double型啊...[/quote] 2.345变成二进制是无限小数，而计算机只能保存有限位，所以实际上存成了跟它最接近的那个有限小数了[/quote] 2.345和2.00345e2保存的方法不同？一个是略大一个是略小？这个行为是无法预测的全看编译器实现吗？[/quote] 要看浮点数用的什么编码。二进制中只有分母是2的幂的分数才能是有限小数，而编码只能针对有限位的。几乎所有的浮点数都不准确，因为表示的范围太大，含有无穷多个数，而只有有限个数是准确的[/quote] 我还是没弄明白之前的问题，2.345存储略大2.00345e2存储略小，它们不都是double？

user: user-4
content: 引用 5 楼 qq_29120981 的回复:[quote=引用 4 楼 wang0635的回复:][quote=引用 3 楼 qq_29120981 的回复:] [quote=引用 1 楼 user-5的回复:]2.00345e2作为double实际上是200.3449999999989, 所以四舍五入会失败 2.345也是double型啊...[/quote] 2.345变成二进制是无限小数，而计算机只能保存有限位，所以实际上存成了跟它最接近的那个有限小数了[/quote] 2.345和2.00345e2保存的方法不同？一个是略大一个是略小？这个行为是无法预测的全看编译器实现吗？[/quote] 要看浮点数用的什么编码。二进制中只有分母是2的幂的分数才能是有限小数，而编码只能针对有限位的。几乎所有的浮点数都不准确，因为表示的范围太大，含有无穷多个数，而只有有限个数是准确的

user: user-0
content: 引用 4 楼 wang0635的回复:[quote=引用 3 楼 qq_29120981 的回复:] [quote=引用 1 楼 user-5的回复:]2.00345e2作为double实际上是200.3449999999989, 所以四舍五入会失败 2.345也是double型啊...[/quote] 2.345变成二进制是无限小数，而计算机只能保存有限位，所以实际上存成了跟它最接近的那个有限小数了[/quote] 2.345和2.00345e2保存的方法不同？一个是略大一个是略小？这个行为是无法预测的全看编译器实现吗？

user: user-4
content: 引用 3 楼 qq_29120981 的回复:[quote=引用 1 楼 user-5的回复:]2.00345e2作为double实际上是200.3449999999989, 所以四舍五入会失败 2.345也是double型啊...[/quote] 2.345变成二进制是无限小数，而计算机只能保存有限位，所以实际上存成了跟它最接近的那个有限小数了

user: user-0
content: 引用 1 楼 user-5的回复:2.00345e2作为double实际上是200.3449999999989, 所以四舍五入会失败 2.345也是double型啊...

user: user-4
content: 几乎所有的浮点数都不准确

user: user-5
content: 2.00345e2作为double实际上是200.3449999999989, 所以四舍五入会失败