10.3969/j.issn.1671-489X.2019.04.044
深析C语言浮点型数据的输入输出
◆方星星  吕永强
摘  要 C 语言的基本数据类型分为:整型、字符型和浮点型,大多C 语言教材都概括了整型和字符型数据的编码及输入输出,但并未详细介绍浮点型数据的编码及输入输出,这导致很多学生不能灵活运用这一知识点。本文为了弥补教材的不足和便于学生更好掌握浮点数的输入输出,首先分析了float 和double 数据的编码,再归纳出浮点型数据按十进制、二进制和十六进制输出的三种方法,最后结合内存结构和具体事例对float 数据double 数据的输入作了深入分析,并阐述了double 数据%f 和%lf 输入的区别。
关键词 输入输出;%f 和%lf;浮点型数据;C 语言中图分类号:G642    文献标识码:B 文章编号:1671-489X(2019)04-0044-03
Deeply Analyzing Input and Output of C Language Floating-point Data //FANG Xingxing, LYU Yongqiang
Abstract  The basic data types of C language are divided into integer, character type and fl oating-point. Most of the C language textbooks summarize the encoding and the input and output of integer a
nd character data, but do not introduce the encoding and the input and output of fl oating-point data in detail, which leads to the fact that many students cannot use this knowledge fl exibly. In order to make up for the defi ciency of the textbook and make it easier for students to better master the input and output of fl oating point numbers, this paper first analyzes the encoding of float and double data, then summarizes three methods of fl oating-point data output by decimal, binary and hexadecimal system, and fi nally makes an in-depth analy-sis of the input of double data of fl oat data combined with memory structure and specifi c cases, and explains the difference between the input of double data by %f and by %lf.
Key words  input and output; by %f and by %lf; fl oating-point data; C language
1 前言
浮点数即实数,分为单精度(float 或single)、双精度(double)和长双精度(long double)三类。精度越高,则该类型表示的数据取值范围越大,占内存字节数越多。在C 语言中,一般只涉及float 类型和double 类型数
作者:方星星,陆军炮兵防空兵学院,讲师,研究方向为计算机网络、计算机软件技术;吕永强,陆军炮兵防空兵学院,讲师,研究方向为多媒体技术(230031)。
据,教材对于两者的输入输出都有所介绍,但对于浮点数的编码原理、十进制以外的输出形式、数据输入的原理等方面的内容提及较少。除此以外,不少教材在描述浮点型数据输入输出时,虽然指出double 型数据的输入只能用%f,输出可以用%f,也可以用%lf,但并未指明原因。以上诸多因素致使学生在学习时有很多困惑。为答疑释惑,本文从浮点数编码、浮点数的三种输出形式、float 数据输入和double 数据输入等四个方面来阐述浮点数的输入输出。
2 float和double数据的编码
浮点数的二进制编码不同于整型数和字符型数。1985
年,为了统一浮点数的存储格式,IEEE
标准。目前,绝大多数计算机都遵守这一标准,极大地改善了各种软件的可移植性。ANSI C double 进行编码。
float 数据的编码  根据IEEE 754的规定,浮点数在编码时首先要进行规格化,即用如下形式表示:
规格化数=符号位·尾数
其中,符号位为0或1,分别表示正数或负数;尾数是形式为1.XXX…XXX 的二进制数,小数点之前为
于特殊情况,需要特殊处理);n 为指数,二进制形式(习惯上写成十进制)。
float 数据存储时占四个字节(32定各位的意义及格式如图1所示。
在存储时,尾数中的“1.”不存储,另外,阶码等于规格化中的指数加上127,即阶码=指数+127。因为指数可以是负数,取值范围是-126~127(-127预留为特殊使用),为了便于处理负指数的情况,IEEE 754标准要求指数加上127后存储。如float 数据1.23经过规格化后为1.0011101 01110000 10100100×20(尾数考虑二进制进位),存储时的指数为0+127=127=01111111,因此,float 数据1.23的最终的存储格式如图2所示。
double 数据的编码  双精度浮点数的规格化过程同float 数,但在存储格式上,双精度浮点数占八个字节(64
图1  单精度浮点数(float)的存储格式
IEEE 制定了IEEE 754守这一标准,极大地改采用该标准对float 和形式表示:尾数×2n 示正数或负数;尾数是数点之前为1(但0属指数,二进制形式(习32位),IEEE 754规,目的是节省存储空间。)的存储格式·技术在线 
- 44 -
2019年2月下 第04期(总第454期)
图4
位),IEEE 754规定各位的意义及格式如图3所示。其中符号位、阶码和尾数分别占1、11和52位。另外,阶码=规格化中的指数+1023。
如double 数据1.23经过规格化后为1.00111010111000010100 01111010 11100001 01000111 10101110×20
(尾数考虑进位),存储时的指数为0+1023=1023=01111111111,因此,double 数据1.23的最终存储格式如图4所示。
与单精度相比,双精度浮点数的阶码和尾数的位数更长,因此,双精度所能表示的数值范围更大且精度更高,可提供更多的有效数字位数,float 变量只能接收十进制有
效位数为7位,而double 变量能接收16位有效数字。
浮点数有十进制、二进制和十六进制三种输出形式,但是大多数的教材只介绍了十进制形式的输出。需要说明的是,十进制形式分为小数形式和指数形式,本文只介绍小数形式输出。另外,为便于深入
分析用%f 和%lf 输入浮点数时的真实值,在此延伸介绍浮点数的二进制和十六进十进制输出(小数形式)  格式说明:%f 是将浮点数以小数形式输出。float 型数据用%f 输出,doule 型数据printf 是一个可变长度列表的函数,函数时,float 会自动转换成double 类型,函数无法区分float 类型和double 类型函数中的%f 既可以用于float 数据输出,数据输出。如果变量类型为float,则只输出四个字节对应的浮点数;如果变量类型为double,会输出八个字节对应的浮点数。需要说明的是,double 变量最多能接收16位有效数字,%f 默认只输出小数点后6位,如果要输出更多有效位数,要加修饰符.n,即%.nf(.n 表示输出小数的位数)。如%.16f 用于输出小数点后16位。
十六进制输出  格式说明:%x 一般用于整型数据的十六进制输出,如果用于浮点数,则是将浮点数的二进制编码以十六进制输出。float 数的十六进制输出用%x,double 数的十六进制输出用%llx。如float 数1.23和double 数1.23按十六进制输出的结果分别为3f9d70a4和3ff3ae147ae147ae(读者可自行验证)。
二进制输出  二进制输出没有对应的格式说明,需要编写程序将变量的每个字节按二进制位进行输出。设计程序时,引入一个共用体,包含字符数组和浮点型变量两个成员,它们共用四个字节或八个字节的存储空间,定义形式如下:
union bianma{char ch[4];fl oat a;}    //处理double 时成员定义为char ch[8];和double a;
将字符数组元素按从后到前的顺序进行排列,每个元
素都以二进制输出,最终的输出结果即为该浮点数的二进制输出。字符数据以二进制形式输出,需要进行二进制位的移位运算,对应的程序代码如下:
voidtra(char ch){ int i;
char mask=(~0)<<7;
for(i =1;i<=8;i++)
{putchar(ch&mask?’1’:’0’); ch=ch<<1;}
}
根据以上分析,再编程写出完整程序,得出float 数1.23的输出结果如图5所示。
double 数1.23的输出结果如图6所示。
4 float数据的输入
浮点型变量float
文中的浮点型数据输入仅指十进制小数形式的输入。float 数据的输入用%f,说明输入的是十进制小数。格式说明:%f 指明输入的数据按float 型处理,系统将此数据按float 类型编码后存入变量占用的四个存储单元中。存储时,低地址存储单元存放数据的低字节,高地址存储单元用于存放数据的高字节。如执行语句段float a;scanf (“%f”,&a);时,键盘输入1.23,则变量a 占用的四个内存单元值如图7所示(假设变量a 的地址为2000H)。
5 double数据的输入
正确实现double 数据的输入(只考虑十进制小数形式)只能用%lf,如果改用%f,则输入不当。
用%lf 输入double 数  此用法能实现正确输入,过程同float 数据的输入。格式说明:%lf 指明输入的数据
(下转P48)
图2
图3  双精度浮点数(double )的存储格式 图6
图7  变量a 的值(float 数1.23)
图5
dou 3 浮点数的输出
浮点数有十进制、
但是大多数的教材只介的是,十进制形式分为小数形式输出。另外,点数时的真实值,在此制输出。
十进制输出(小数以小数形式输出。flo 一般用%lf 输出。由于当调用printf 函数时其结果是printf 函数参数。因此,printf 函数也可以用于double 数只输出四个字节对应的会输出八个字节对应的技术在线·
- 45 -
2019年2月下 第04期(总第454期)
一些压缩算法中涉及参数设置,如LZW算法的压缩步长,一般选择为2的n次方,即每次压缩2n×2n个数据,将原图像进行分块压缩。可通过软件界面进行参数设置。
对于学生教学而言,这种界面布置更加简洁清晰,将压缩前后图像差别以及相关参数放置在一个界面中,学生可明显看出压缩前后的区别,可以更加深刻地了解有损压缩对于图像数据的损失程度,以及无损压缩压缩时间上的缺陷。
GUI界面运行  运行GUI的步骤:打开GUI的可编辑界面,点击运行按钮,即可运行GUI界面,如图2所示。通过GUI进行仿真的步骤:打开GUI界面点击运行,选择好算法,点击确认按钮,等待图像和数据的显示。可再次选择其他算法进行多组不同实验,也可多次实验同一种算法,促使学生思考每次运行结果产生微小差异的原因。
5 结语
通过图像压缩算法的研究,提出基于客观和主观的综合评价指数,对图像压缩效果进行评价;基于GUI图形界面,设计实现无损压缩和有损压缩的六种算法,包括RLE算法、Huffman编码、LZW编码、算术编码、DCT算法和小波变换。通过图像压缩软件,可以让学生直观比较不同压缩算法的运行效果和特点。所设计的综合评价指数,不仅可以让学生通过实验分析有损压缩和无损压缩的区别、不同压缩算法的压缩效果和最佳参数设置,而且可以启发学生进行更多的科研探索,结合所处理的图像类型,设计更好的编码和评价指标。■
参考文献
[1]张春田,苏育挺,等.数字图像压缩编码[M].北京:清华大学出版社,2006.
[2]萨洛蒙.数据压缩原理与应用[M].北京:电子工业出版社,2008.
[3]冈萨雷斯,伍兹.数字图像处理[M].3版.北京:电子工业出版社,2011.
[4]吴晓云.算术编码算法在图像压缩中的研究[J].计算
机与数字工程,2017,45(9):1863-1865.
[5]冯飞,刘培学,李晓燕,等.离散余弦变换在图像压缩
算法中的研究[J].计算机科学,2016(S2):240-241,255.
[6]宗节保,段柳云,王莹,等.基于
方法的研究与实现[J].电子设计工程
图2  运行GUI界面
图8  变量b的值(double数1.23)图9  内存中变量e的值
按double处理,系统先将此数据按double类型编码,再
存入变量占用的八个存储单元中。如执行语句段double
b;scanf(“%f”,&b);时,输入1.23,则变量b占用的八
个内存单元值如图8所示(假设变量b的地址为2000H)。
用%f输入double数  该用法不能正确输入double数。
如执行语句double e;scanf(“%f”,&e);时,输入1.23,
变量e的值为0。这是由于%f指明输入的数据只按float
类型处理,数据按float类型编码后只存放到e占用的前
四个存储单元中,即低地址存储单元。而变量e实际占用
八个存储单元,系统自动将0存储到四个高地址存储单元,
因此,变量e占用的八个内存单元真实值如图9所示(假
设变量e的地址为2000H)。不难得出,这八个字节对应的
double数十进制值为0(有效位数为15位),因此,执行
语句printf(“%lf”,e);后,得出e
6 结语
为便于掌握%f和%lf的用法,
double数据的编码原理基础上,提出浮点数的三种输出方法,
再分别介绍float和double数据的输入,最后总结
数据用%f和%lf进行数据输入的区别。由于浮点数的编码较
为复杂,C语言又严格规定了%f和%lf
数的输入输出不同于整型和字符型,不便于掌握。在实际应
用中,为避免数据输入输出结果不一致,建议
入输出统一用%f,double数据输入输出统一用
参考文献
[1]谭浩强.C程序设计[M].4版.北京:清华大学出版社,
2010.
[2]张亚玲.大学计算机基础:计算思维初步[M].北京:
清华大学出版社,2014.
[3]朱亚超.基于IEEE 754的浮点数存储格式分析研究[J].
计算机与信息技术,2006(9):50-52.
[4]田祎,樊景博.C语言中浮点数的表示范围浅析[J].软
件工程,2016(4):8-10.
[5]IEEE Standard for Binary Floating-Point Arithme-
tic.ANSI/IEEE Standard 754-1985[M]//Institute of
Electrical and Electronics Engineers.1985.
(上接P45)
散余弦变换在图像压缩
(S2):240-241,255.
于MATLAB GUI软件制作
程,2010,18(7):54-56.
的值为0。
本文在分析float和
浮点数的三种输出方法,
输入,最后总结double
。由于浮点数的编码较
f的用途,因此,浮点
不便于掌握。在实际应
致,建议float数据输
出统一用%lf。■·技术在线 
- 48 -
2019年2月下 第04期(总第454期)

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。