C++浮点数format时的舍入问题

C++浮点数format时的舍入问题

首先有这样一段代码:

#include <iostream>
#include <stdio.h>
using namespace std;

int main() 
{
    cout << " main begin : " << endl;

    printf("%.0f \r\n", 1.5);
    printf("%.0f \r\n", 1.51);
    printf("%.0f \r\n", 2.5);
    printf("%.0f \r\n", 2.51);

    return 1;
}

预期输出是什么?
我以为按照四舍五入会输出 2 2 3 3
但是实际结果:
在这里插入图片描述

其他的都没问题,只有 2.5 保留一位小数时是2不是3有点奇怪,然后查了文档,最后找到这样一段:

从 Windows 10 版本 2004(内部版本 19041)开始,printf 系列函数根据 IEEE 754 的舍入规则输出可精确表示的浮点数。 在早期的 Windows 版本中,以“5”结尾并且可精确表示的浮点数总是向上取整。 IEEE 754 规定它们必须舍入到最接近的偶数(也称为“四舍六入五成双”)。 例如,printf(“%1.0f”, 1.5) 和 printf(“%1.0f”, 2.5) 都应舍入为 2。 之前,1.5 舍入为 2,2.5 舍入为 3。

来源:MSDN-learn

也就是IEEE 754的标准规定了“四舍六入五成双”这种取整方式,而像是IEEE 754这类标准我以前从没有仔细了解过,遇到也只是简单扫一眼就过去了,所以才会遇到今天这个问题而不理解;

IEEE 754 是什么:
IEEE二进制浮点数算术标准(IEEE 754)是20世纪80年代以来最广泛使用的浮点数运算标准,为许多CPU与浮点运算器所采用。这个标准定义了表示浮点数的格式(包括负零-0)与反常值(denormal number),一些特殊数值(无穷∞与非数值NaN),以及这些数值的“浮点数运算符”。 常见的四种浮点数值表示方式:单精确度(32位)、双精确度(64位)、延伸单精确度(43比特以上,很少使用)与延伸双精确度(79比特以上,通常以80位实现)。C语言的float通常是指IEEE单精确度,而double是指双精确度。

这个标准我也还在学习了解中,就不介绍了;
回到刚才的format问题,刚才给出原因的MSDN页面上也给出了解决方式,对于MSVC系列编译器可以通过添加 legacy_stdio_float_rounding.obj 来变为正常的四舍五入,试一下:
在这里插入图片描述

之后重新运行会发现format规则已经变为了四舍五入:
在这里插入图片描述

但是这个选项仅仅是针对MSVC系列编译器起效的,G++我没有找到类似的属性,如果有人知道麻烦评论告知一下,感激不尽;
在这里插入图片描述

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
c11 format头文件是C语言中提供格式化输入输出功能的头文件。包含在该头文件中的函数和宏能够以指定的格式读取输入并以指定的格式输出数据。 该头文件提供了格式化输出函数printf和fprintf,它们可以根据指定的格式将数据打印到屏幕或文件中。printf函数是将输出打印到标准输出设备(通常是屏幕),而fprintf函数则是将输出打印到指定的文件。 格式化输入函数如scanf和fscanf能够根据指定的格式从输入源(键盘或文件)读取数据。scanf函数从标准输入设备(通常是键盘)读取数据,而fscanf函数则从指定的文件中读取数据。 在格式化字符串中,可以使用各种转换说明符来指定输出或输入的数据类型。例如,%d表示要输出或输入一个整数,%f表示要输出或输入一个浮点数,%s表示要输出或输入一个字符串等等。通过使用不同的转换说明符,我们可以控制数据的打印或读取格式。 除了转换说明符外,还可以使用一些修饰符来更精确地控制打印或读取的数据格式。例如,可以使用精度修饰符来控制浮点数的小数位数,宽度修饰符来指定输出字段的宽度,标志修饰符来指定一些特殊的输出方式等等。 总之,c11 format头文件提供了一组强大的函数和宏,使得我们能够以灵活的方式控制数据的格式化输出和输入。这对于在程序中进行数据的打印和读取是非常有用的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值