printf("%d",5.01)和printf("%f",5)的输出结果

倍福TC3 PLC高速采集实战:如何用PLC-Recorder实现0.24ms级时间戳同步 本文详细介绍了倍福TC3 PLC与PLC-Recorder实现0.24ms级时间戳同步的工程实践方案。通过硬件拓扑设计、时间源选择优化、报文结构封装及同步验证方法,为工业自动化领域的高精度数据采集提供了可靠解决方案,特别适用于精密装配、激光切割等微秒级同步要求的场景。 阅读详情
   printf("%f\n",5);
   printf("%d\n",5.01);
   printf("%f\n", (float)5); 
   printf("%f\n", 5.f); 


输出结果:

$ ./test
0.000000
1889785610
5.000000
5.000000

看到结果,会感觉非常奇怪。1处怎么会输出0呢?2又为何会显示这么大的一个数呢?

解释:

下面是转自网上的一篇博客的解释

1,之所以没输出5,这是C语言设计的原因。
2,之所以输出0,这是计算机体系结构的问题。

具体来说:

printf函数不会进行任何类型转换,它只是从内存中读出你所提供的元素的值(按照%d,%f等控制字符提示的格式)。C语言设计中,int类型一般是32bit或者16bit,而float一般是64bit,并且有可能使用科学计数保存。这点就和huhugo88所说一样,5在内存中为00000000,00000101。而且5一般都在静态区,程序的静态存储区默认是0,那么当用%f来读时,就会读64bit,也就是会读之前的很多位0,最后按照(有效数字)×(基数2)pow(指数)的方式来取数,自然结果是0

之所以Vc中不允许这种情况,而有些编译器就允许这么输出就是编译器设置的问题。按理说,这样访问内存是属于越界访问,应该禁止。不过只是读,伤害性不大而已。  对于单精度浮点数(32bit),不少c语言编译系统以24位表示小数部分(包括1bit符号位),以8位表示指数部分。

浮点数的二进制表示格式可参考计算机体系结构

==========================

printf("%d\n",5.01);  为什么输出一个大数?在讲这个题目之前,预备知识,讲一下,printf函数,输入参数是读入缓冲区保存,再按照%?的格式从缓冲区中读出数据,并据此格式解释数据。

有了这个知识之后,在讲程序员面试宝典上看到一个题:

#include "stdio.h" 
int main(int argc, char* argv[])   
{   
    printf("%d\n",5.01);   
return 0;   
}   
输出结果为:188978561  
然后开始研究为什么会是这个数?

5.01是double类型,内存中占8个字节,保存在缓冲区。而%d为整型,占4个字节,printf从缓冲区中读入4字节,先读到低32位的数据。

也就是说printf输出的应该是5.01以double类型保存数剧的低32位。为了检验此结果是否正确,对比5.01在内存中的表示与输出。

#include "stdio.h" 
int main(int argc, char* argv[])   
{   
double d = 5.01;   
int *p = (int *)(&d);   
int rst = 1889785610;   
    printf("1).%x\n",*p);   
    printf("2).%x\n",*(p+1));   
    printf("3).%x\n",rst);   
return 0;   
}   
输出为:   
1).0x70a3d70a   
2).0x40140a3d   
3).0x70a3d70a  
这也就证明了%d输出了5.01的低32低。5.01的double类型,在内存的的表示为0x40140a3d70a3d70a。

事情看似也就完成了。

我又想,如果输入是浮点类型的5.01f,又会发生什么呢?

#include "stdio.h" 
int main(int argc, char* argv[])   
{   
    float f = 5.01f;     
    int *p = (int *)(&f);        
    printf("1).0x%x\n",*p);     
    printf("2).0x%x\n",5.01f);     
return 0;     
}   
输出:   
1).0x40a051ec   
2).0x80000000  
我们发现,此时输出的并不是浮点类型5.01f的内存的表示,这是为什么呢?

然后看到一个说法,是printf会把%f按double类型输出,也就是说会把参数float型的转成double型在输出。

但现在并不是%f,当然用%f显示的是正确的结果。于是我猜测,printf是将所在float型读入的数据都自动的转化为double型了,然后%f就按double处理,而我们这是%d,所以显示的为float转化为double型后的低4字节。

验证此想法:

#include "stdio.h" 
int main(int argc, char* argv[])   
{   
double f = 5.01;     
int *p = (int *)(&f);   
    printf("1).0x%x\n",*p);   
    printf("2).0x%x\n",*(p+1));     
    printf("3).0x%x\n",5.01f);     
return 0;     
}   
输出:   
1).0x70a3d70a   
2).0x40140a3d   
3).0x80000000  
但是我们发现结果并不一样,于是我又猜想,也是许printf将float转化为double的方式与默认的方式不一样

5.01d的默认的表示为:0x40140a3d70a3d70a,在上面已经说明了

#include "stdio.h" 
int main(int argc, char* argv[])   
{   
    printf("0x%8x\n0x%8x\n",5.01f);   
return 0;   
}   
输出为:   
0x80000000   
0x40140a3d  
与是发现printf将5.01f->5.01d的表示是:0x40140a3d80000000

接着就是看这两个值是否都是为5.01了:

view plaincopy to clipboardprint?

#include "stdio.h" 
int main(int argc, char* argv[])   
{   
int d1[2], d2[2];   
    d1[0]=0x80000000;   
    d1[1]=0x40140a3d;   
    d2[0]=0x70a3d70a;   
    d2[1]=0x40140a3d;   
double *p1 = (double *)d1;   
double *p2 = (double *)d2;   
    printf("1).%f\n",*p1);   
    printf("2).%f\n",*p2);   
return 0;     
}   
输出为:   
1).5.010000   
2).5.010000  
也就证明了0x40140a3d80000000,与0x40140a3d70a3d70a都是5.01d在机器中的表示。前者为5.01f(0x40a051ec)由printf转化为double后的表示,后者为5.01d的默认的表示。

总结:printf将输的浮点型参数全都自动转化为双精度型,且与默认的双精度的表示方法是不同的。最重要一点,printf不安全,类型不安全,要是类型不对了,也许我们就挂了^_^


本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/fengyunjh/archive/2011/03/07/6230164.aspx

 

=======================================================================================================================

通过以上解释,我们大致明白:

1. printf输出float型时,会自动转化成double型;

2. 由于存储时,都是先低位,再高位,同时经过转化成double,前面会取很多0(越界访问);

3. 5.01,打印时按照int来取,只取前四个字节。

RoboMaster机甲大师赛备赛:如何用STM32+CAN总线精准控制四个大疆3508电机? 本文详细介绍了在RoboMaster机甲大师赛中,如何利用STM32和CAN总线技术精准控制四台大疆3508电机。从硬件架构设计、多电机ID分配、数据解析到同步控制算法,全面解析了构建高响应、低延迟底盘驱动系统的关键技术,助力参赛队伍提升机器人运动性能。 阅读详情

相关推荐

手把手教你做基于stm32的红外、语音、按键智能灯光控制(上)

这次项目使用的板子是stm32f103c8t6最小系统板,这个板子在tb上都能够买到,随便一个最小系统板都可以,== 注意在买最小系统板的时候需要买一个stlink下载器来下载程序。显示模块是使用的0.96英寸的OLED屏幕,注意是使用的IIC通信协议的OLED屏幕,不是使用SPI总线协议的。这次写的代码还顺便集成了检测温湿度的功能,所以要使用DHT11温湿度传感器,来采集温度。本文所设计的基于单片机的灯光控制系统主要由模式选择功能、手动模式和自动模式组成。LED灯自然就是要控制的部件了。

nbbskk的博客 6556

关于 printf("%d",5.01)的输出

又上文float储存类型可以知道,5.5 = 1.011*2^2(2进制)二进制为  0 1000 00001 011.............0(23位) 所以= 2^30+........ = 很大的数  而  printf("%f",5) 对于5  = 101(二进制)  解释称 float类型, 那是相当的小啊.. 于是 输出0.0指数位: 0000 0

zjumath的专栏 1750

Reeds-Shepp曲线公式推导及代码实现-第二部分(共三部分)

文章目录2. Reeds-Shepp求解2.1 L+S+L+L^+S^+L^+L+S+L+2.2 L+S+R+L^+S^+R^+L+S+R+2.3 L+R−L+L^+R^-L^+L+R−L+2.4 L+R−L−L^+R^-L^-L+R−L−2.5 L+R+L−L^+R^+L^-L+R+L−2.6 L+Rβ+Lβ−R−L^+R_{\beta}^+L_{\beta}^-R^-L+Rβ+​Lβ−​R−2.7 L+Rβ−Lβ−R+L^+R_{\beta}^-L_{\beta}^-R^+L+Rβ−​Lβ−​R+2.8

jianmo的博客 1210

c语言的printf输出浮点数的一些问题

在printf时:如果以%f格式输出,将输出8个字节(scanf输入时,%f是4个字节)                    在参数入栈时如果是float型或者double型 直接入栈8个字节,此时输出及后续输出都没问题                     但如果参数小于8个字节且不是float型:比如int   shor int  ,就会扩展符号位,成为4个字节再入栈,但是输出的是8个

aa838260772的专栏 1万+

【Python】SimpleITK使用笔记

1. 概念 1.1 nii格式 1.2 SimpleITK 1.3 SimpleITK 图像 2. 基本操作 2.1 常见属性 2.1 读取和保存图像 2.2 SimpleITK图像数据和Numpy矩阵数据之间的转换

See_Star的博客 7894

FID指标实战:如何用Python快速计算生成图像的质量分数(附完整代码)

本文详细介绍了如何使用Python计算Fréchet Inception Distance(FID)指标,以评估生成图像的质量。通过完整的代码示例和优化技巧,帮助开发者快速实现FID计算,并解读分数背后的实际意义,适用于GAN和扩散模型的性能评估。

weixin_28718487的博客 374

c语言打印字符占位4字符,C语言的常用printf打印占位符%d, %f, %s, %o, %x

占位符含义及用法代码:#include int main(int argc, char const *argv[]){int a = 12, b = 20; // 默认10进制赋值char *str = "jack";// %d 为整数占位符,10进制表示printf("a + b = %d\n", a + b);// %o 为整数占位符,8进制表示printf("a = %d, 8进制为 %o\...

weixin_31554959的博客 2924

HandwrittenMathFormulaRecognition:基于YOLOv8的手写数学公式识别系统

输入:包含手写数学公式的图像(拍摄的板书、作业纸等)输出:对应的数字文本形式的数学公式(如LaTeX格式或文本表达式)标准的手写数学表达式数据集,包含在线轨迹及图片,广泛用于公式识别研究。包含近10万对公式图片及对应的LaTeX标注,适合训练公式识别模型。MathBrush公开手写数学公式图像数据集,含多种书写风格。手写数字与符号数据集(MNIST及其扩展)用于基础数学符号的训练。

YOLO 283

数据类型和符号

1011-数据类型基本数据类型整数(只要是不带小数点的数,默认int)byteshortintlong浮点(只要是带小数点的数,默认double)floatdouble字符(默认char)char 表示单个字符,用一对 ''括起来布尔(默认bool)Boolean标识符变量关键字运算符算数运算符+ - * /%++ -- 基本数据类型 整数(只要是不带小数点的数,默认int) byte 在内存中的...

Zoya_R的博客 1989

69页完整版智慧港口综合解决方案

智慧港口需求4港机远程操控等自动化改造需求自动化码头AGV无线通信及专用视频系统需求安全生产视频监控类需求港机RCMS及设备管理需求岸边智能理货码头三维全景应用智慧港口解决方案5自动化码头AGV/跨运车/无人集卡无线接入港机远控视觉及冗余无线通信视觉集卡防吊起系统集装箱码头岸边智能理货港机RCMS系统无线接入港机智能化管理(无线高清视频监控、一键报警、远程抄表系统)港口拖轮无线接入岸边溢油监测系统TD-LTE覆盖及业务终端接入港口生产管理系统港口可视化集群调度港口GiNMS综合网络设备智能管理全球作业效率最

zuoan1993的博客 2128

执行HDevelop项目

这一节,我们讲述的是如何用HDevEngine加载和执行一个HDevelop项目。代码部分来源于示例程序exec_program(源文件exec_program.cpp),检测塑料零件边界上的毛刺。1.Step 1:初始化首先,我们包含HALCON/C++和HDevEngine头文件以及命名空间。注意到在这个示例程序中,HDevEngine头文件已经包含在my_hdevoperatorimpl中,所

Z's Palace 2994

printf("%f",5)的输出结果

#include <stdio.h> void main() { printf("%f\n",5); printf("%d\n",5.01); printf("%f\n", (float)5); printf("%f\n", 5.f); } printf函数不会进行任何类型转换,它只是从内存中读出你所提供的元素的值(按照%d,%f...

Eyrane的博客 5087

【全局路径规划模块运动学算法】无人机Kinodynamic A*算法、Kinodynamic RRT*算法(附C++代码)

认知有限,望大家多多包涵,有什么问题也希望能够与大家多交流,共同成长!本文先对Kinodynamic A*算法做个简单的介绍,具体内容后续再更,其他模块可以参考去我其他文章提示:以下是本篇文章正文内容啃这个Kinodynamic A_star算法,建议先啃一啃高飞fast_planner那篇论文,把理论打好,如果还是比较迷,就先看Dijksta、再看A_star、再看hybrid A_star 三个的流程,因为往上资料比较多,再看这个Kinodynamic A_star算法,流程已经很相像了。如果。

qq_35635374的博客 2597

printf中用%d输出float或者double

首先说一个“默认参数提升”的概念: If the expression that denotes the called function has a type that does include a prototype, the arguments are implicitly converted, as if by assignment, to th...

aobi6343的博客 1799

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

【转】printf("%f/n",5)的输出结果为什么是0.000000

1,之所以没输出5,这是C语言设计的原因。 2,之所以输出0,这是计算机体系结构的问题。 具体来说: printf函数不会进行任何类型转换,它只是从内存中读出你所提供的元素的值(按照%d,%f等控制字符提示的格式)。 C语言设计中,int类型一般是32bit或者16bit,而float一般是64bit,并且有可能使用科学计数保存。这点就和huhugo88所 说一样,5在内存中为00000000,00000101。而且5一般都在静态区,程序的静态存储区默认是0,那么当用%f来读时,就

fengyunjh的专栏 9977

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

在c语言中执行这两条语句printf("%d/n", 5.01);printf("%f/n", 5);

在c语言中执行这两条语句 printf("%d/n", 5.01); printf("%f/n", 5); 说这两条语句最后执行结果不是输出5和5.000000 而是输出了一个和大的数(我自己执行的是1789985710)和0.000000。 是感觉非常的不可思议。。。。。。。。 其实,在我们当我们弄清楚浮点数的存储格式之后,就会明白其中的奥妙了。 在C语言标准中,浮点数是采用IEEE754标准 float类型数据存储格式如下: 最高位最低位符号S 阶码E 尾数M 最高位 31 位 ,保存符号位

qwer_boo 的专栏 3064

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

printf("%f\n",5);/

printf("%f\n",5);// 因为内存越界了 5: int ;  flaot转double 8字节。 结果: 0.0000    printf("%d\n",5.0);//0    printf("%d\n",5.01);// 大数未知 浮点存储于定点存储不一样。     char cChar1[]="o\0w";    cout    cout    char cC

landywyliu专栏 1504
上一篇: 字节那些事儿
下一篇: Linux内核入门(二)——用户态向内核态切换
废言Pro
博客等级 码龄16年 1092粉丝 142原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值