方星星 吕永强

摘  要 C语言的基本数据类型分为:整型、字符型和浮点型,大多C语言教材都概括了整型和字符型数据的编码及输入输出,但并未详细介绍浮点型数据的编码及输入输出,这导致很多学生不能灵活运用这一知识点。本文为了弥补教材的不足和便于学生更好掌握浮点数的输入输出,首先分析了float和double数据的编码,再归纳出浮点型数据按十进制、二进制和十六进制输出的三种方法,最后结合内存结构和具体事例对float数据double数据的输入作了深入分析,并阐述了double数据%f和%lf输入的区别。

关键词 输入输出;%f和%lf;浮点型数据;C语言

中图分类号:G642    文献标识码:B

文章编号:1671-489X(2019)04-0044-03

Abstract The basic data types of C language are divided into integer, character type and floating-point. Most of the C language textbooks summarize the encoding and the input and output of integer and character data, but do not introduce the encoding and the input and output of floating-point data in detail, which leads to the fact that many students cannot use this knowledge flexibly. In order to make up for the deficiency of the textbook and make it easier for students to better master the input and output of floating point numbers, this

paper first analyzes the encoding of float and double data, then summarizes three methods of floating-point data output by decimal, binary and hexadecimal system, and finally makes an in-depth analy-

sis of the input of double data of float data combined with memory structure and specific 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; floating-point data; C language

1 前言

浮点数即实数,分为单精度(float或single)、双精度(double)和长双精度(long double)三类。精度越高,则该类型表示的数据取值范围越大,占内存字节数越多。在C语言中,一般只涉及float类型和double类型数据,教材对于两者的输入输出都有所介绍,但对于浮点数的编码原理、十进制以外的输出形式、数据输入的原理等方面的内容提及较少。除此以外,不少教材在描述浮点型数据输入输出时,虽然指出double型数据的输入只能用%f,输出可以用%f,也可以用%lf,但并未指明原因。以上诸多因素致使学生在学习时有很多困惑。为答疑释惑,本文从浮点数编码、浮点数的三种输出形式、float数据输入和double数据输入等四个方面来阐述浮点数的输入输出。

2 float和double数据的编码

浮点数的二进制编码不同于整型数和字符型数。1985年,为了统一浮点数的存储格式,IEEE制定了IEEE 754标准。目前,绝大多数计算机都遵守这一标准,极大地改善了各种软件的可移植性。ANSI C采用该标准对float和double进行编码。

float数据的编码  根据IEEE 754的规定,浮点数在编码时首先要进行规格化,即用如下形式表示:

规格化数=符号位·尾数×2n其中,符号位为0或1,分别表示正数或负数;尾数是形式为1.XXX…XXX的二进制数,小数点之前为1(但0属于特殊情况,需要特殊处理);n为指数,二进制形式(习惯上写成十进制)。

float数据存储时占四个字节(32位),IEEE 754规定各位的意义及格式如图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位),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位有效数字。

3 浮点数的输出

浮点数有十进制、二进制和十六进制三种输出形式,但是大多数的教材只介绍了十进制形式的输出。需要说明的是,十进制形式分为小数形式和指数形式,本文只介绍小数形式输出。另外,为便于深入分析用%f和%lf输入浮点数时的真实值,在此延伸介绍浮点数的二进制和十六进制输出。

十进制输出(小数形式)  格式说明:%f是将浮点数以小数形式输出。float型数据用%f输出,doule型数据一般用%lf输出。由于printf是一个可变长度列表的函数,当调用printf函数时,float会自动转换成double类型,其结果是printf函数无法区分float类型和double类型参数。因此,printf函数中的%f既可以用于float数据输出,也可以用于double数据输出。如果变量类型为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];float a;}    //处理double时成员定义为char ch[8];和double a;将字符数组元素按从后到前的顺序进行排列,每个元素都以二进制输出,最终的输出结果即为该浮点数的二进制输出。字符数据以二进制形式输出,需要进行二进制位的移位运算,对应的程序代码如下:

4 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指明输入的数据按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的值为0。

6 结语

为便于掌握%f和%lf的用法,本文在分析float和double数据的编码原理基础上,提出浮点数的三种输出方法,再分别介绍float和double数据的输入,最后总结double数据用%f和%lf进行数据输入的区别。由于浮点数的编码较为复杂,C语言又严格规定了%f和%lf的用途,因此,浮点数的输入输出不同于整型和字符型,不便于掌握。在实际应用中,为避免数据输入输出结果不一致,建议float数据输入输出统一用%f,double数据输入输出统一用%lf。

参考文献

[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.

c语言浮点数能用八进制输出不,深析C语言浮点型数据的输入输出相关推荐

  1. c语言以16进制输出大写字母,【C语言】十六进制形式输出应用程序

    1.前言 最近在看到同事写了一款封印病毒的程序,非常有意思!原理大致是将PE文件中的ASCII转换成HEX输出到文本中.这样做的目的是为了保存病毒样本的时候不会被杀毒软件查杀!然而却是delphi写的 ...

  2. c语言三个数从小到大排序/输出_我的c语言笔记(三)

    int表达式 这个表达式存在的目的在于将表达式转为整数. 比如: float a=9999.9999: int b; b=(int)(a/1000); 就可以得到9啦,别忘了套上固定格式哦- 然后我们 ...

  3. python语言浮点数可以不带小数部分吗_关于Python语言的浮点数类型,以下选项中描述错误的是 ( )_学小易找答案...

    [单选题]关于Python赋值语句,以下选项中不合法的是 ( ) [简答题]2014年22JAVA_B场参考答案.doc [单选题]下面代码的输出结果是 ( ) d ={" 大海 " ...

  4. c语言ax2bxc0,c语言程序用函数怎么输出ax2bxc=0?用C语言编号一个程序, 爱问知识人...

    解一元二次方程a x2 b x c = 0,a.b.c由键盘输入. 分析:对系数a.b.c考虑以下情形 1) 若a = 0: ① b 0,则x=-c/b : ② b = 0, 则:① c = 0, 则 ...

  5. 深析C语言的灵魂 -- 指针

    文章目录 一.指针基础知识 1.什么是指针 2.指针变量的大小 3.指针类型的意义 4.指针的运算 5.野指针的成因及规避方法 二.指针进阶知识 1.字符指针 2.指针数组 3.数组指针 4.数组参数 ...

  6. 【C语言】浮点型数据在内存中的存储方式

    目录 一. 前言 二. 问题的引出 三. 两类浮点型数据(float.double)在内存中的存储方式 3.1 两类浮点型数据的存储模型 3.1.1 浮点型数据数值读取的通用模型 3.1.2 floa ...

  7. c语言对浮点数的处理默认是double吗,C语言中浮点数float和double输出的问题

    C语言中浮点数float和double输出的问题 关注:260  答案:6  信息版本:手机版 解决时间 2019-01-12 07:33 斑駁影 2019-01-11 09:20 #includev ...

  8. c语言以16进制输出大写字母,C语言二进制、八进制、十六进制整数书写和输出...

    文章目录 一.二进制.八进制.十六进制整数的书写 1.二进制 2.八进制 3.十六进制 4.需要注意的坑 二.二进制.八进制.十六进制整数的输出 三.获取视频教程 四.版权声明 整数是我们生活中常用的 ...

  9. C语言:二进制、八进制、十六进制整数的书写及输出

    目录 一.整型数据类型 二.二进制.八进制.十六进制的书写 1)二进制 以 0b / 0B 开头,不区分大小写(数字0,而非字母o,下同) 2)八进制 以数字 0 开头 3)十六进制 以 0x / 0 ...

最新文章

  1. 自动驾驶产业链全梳理
  2. CCIE PASSED
  3. 近期遇到的一些信号处理的问题,做一下总结
  4. Java学习笔记(13)
  5. Majority Element II
  6. 采用预取(Prefetch)来加速你的网站(转)
  7. restTemplate 传递map
  8. oracle dbf文件设置,oracle移动数据dbf文件
  9. 获取linux详细信息,Linux 获取网口详细信息
  10. 基于智能卡的嵌入式网络加密安全系统设计
  11. 「PDF Expert」macOS 全能型 PDF 工具,几大能力务必了解下
  12. [操作系统] 线程和进程的简单解释
  13. Futter基础第16篇: 实现单行文本框、多选框
  14. protel 99se 层次原理图的切换
  15. 解决Windows无法加载中文(中国)-王码五笔输入法 86版 键盘的布局的方法
  16. McAfee软件下载与安装
  17. R语言ggplot2绘图
  18. 编译原理 —— 四元式和三地址代码
  19. 计算机音乐多幸运,多幸运(伴奏) 韩安旭 多幸运(伴奏)歌曲,多幸运(伴奏)mp3在线试听 - 5nd音乐网...
  20. ELK日志分析平台之kibana以及借助ELK平台实现网站访问量统计

热门文章

  1. 2012年10月底的家乡
  2. 字符串中Emoji表情处理
  3. 中国移动:移动互联网仍是未来发展立足点
  4. 硬盘变成RAW 修复
  5. 802.11成帧封装实现(三)
  6. Python字典嵌套
  7. poj 2942 点双连通分量
  8. Linux中文件传输、解压缩文件
  9. VMware中使用U盘PE系统
  10. 中国宠物泌尿系统处方粮行业销售动态与营销前景预测报告(2022-2027)