请教为什么printf("result is=%f\n",1234567.1);返回的是1234567.125 ?

oracleperl 2021-01-18 01:57:59
请教为什么printf("result is=%f\n",1234567.1);返回的是1234567.125 ?
谢谢
...全文
3821 62 打赏 收藏 转发到动态 举报
写回复
用AI写文章
62 条回复
切换为时间正序
请发表友善的回复…
发表回复
SS哭辽 2021-01-29
  • 打赏
  • 举报
回复
换成%.1f就是输出一位小数了。同理%.3f就是输出3位小数
  • 打赏
  • 举报
回复
.125就是八分之一。说明浮点指数截断后,最后一个阶是二的负三次幂。
兔耳袋狸Bilby 2021-01-26
  • 打赏
  • 举报
回复
……人家跟你说得清清楚楚,你在这里质疑计算机有什么用? 不得不说在我看来你在钻牛角尖。明明自己去学习并实践一下浮点数的十进制如何转二进制就能明白的,建议再去研究一下计算机组成原理,真的明白原理后,我想你的计算机无用论会不攻自破。 另外,我想说计算机不是万能的,他能帮我们提高效率,但是你如果真的想得到特别特别准确,甚至说绝对准确的数据是不可能的。而且现实生活中也不是需要绝对准确的数据,对数据的要求都是在一个可接受的误差范围内,这也是学计算机要学习数值计算方法的原因。绝大多数情况下,我们需要的是满足误差范围的数据。
梦之海岛 2021-01-25
  • 打赏
  • 举报
回复
这种应该算误差吧,要保留1位小数的话用%.1f
黄二黑 2021-01-23
  • 打赏
  • 举报
回复
有效位数超出了
Stock king 2021-01-22
  • 打赏
  • 举报
回复
这个是编译器的问题
赵4老师 2021-01-21
  • 打赏
  • 举报
回复
简短截说 10进制小数就是用1/10,1/100,1/1000,……分 2进制小数就是用1/2,1/4,1/8,……分 N进制小数就是用1/N,1/(N*N),1/(N*N*N),……分 所以如果限制最小的用来分的阶数(也就是小数点后最多多少位),M进制小数和N进制小数对有些数两者都能精确表示,对有些数两者只有其一能精确表示,对有些数,两者都不能精确表示。 如果不限制最小的用来分的阶数(也就是小数点后最多多少位,也就是允许使用无限位,不一定非得是循环小数),那M进制小数和N进制小数都能精确表示任何有理数。
赵4老师 2021-01-21
  • 打赏
  • 举报
回复
引用 52 楼 oracleperl 的回复:
引用
赵老师好 请教下 1. 如果是整数,二进制和十进制互转没有问题对吧? 2.二进制转十进制也是可以精确转的对吧?,比如如下演算 二进制0.1111= 1*(1/2)+1*(1/4)+(1/8)+1/16= 7/8 3. 十进制小数转二进制就不一定能精确转了对吧?似乎是二进制没法记录10进制的所有值 或者说二进制的数值是十进制数值的子集?我这样理解对吧? 但我还没搞明白十进制转二进制的原理
1.对 2.不对 3.对。半对(二进制没法记录10进制的所有值,10进制也没法记录二进制的所有值,二进制的数值和十进制数值之间谁都不是谁的子集)。错。 N(正整数N≥2)进制的小数比如 N=2,2进制: 10.11 W1=1,W0=0,W-1=1,W-2=1其中-1,-2是下标, 对应数值为W1*N^1+W0*N^0+W-1*N^-1+W-2*N^-2其中^表示指数 N=3,3进制: 20.11 W1=2,W0=0,W-1=1,W-2=1其中-1,-2是下标, 对应数值为W1*N^1+W0*N^0+W-1*N^-1+W-2*N^-2其中^表示指数 N=10,10进制: 90.11 W1=9,W0=0,W-1=1,W-2=1其中-1,-2是下标, 对应数值为W1*N^1+W0*N^0+W-1*N^-1+W-2*N^-2其中^表示指数 显然: N=3,3进制 0.1 W0=0,W-1=1,对应数值为W0*N^0+W-1*N^-1即0*3^0+1*3^-1=0.33333333333333无限循环,无法用长度有限的10进制表示 同理,对有些长度有限的10进制小数,无法用长度有限的2进制表示
青蛙工作室 2021-01-21
  • 打赏
  • 举报
回复
引用 46 楼 oracleperl 的回复:
[quote=引用 45 楼 青蛙工作室 的回复:]严重怀疑楼主是来钓鱼提升CSDN的活跃度的,这么一个基础的问题纠缠了5页,而且看楼主的ID,oracle、perl,3年码龄,根本就不像一个刚接触计算机的小白。各位热心的CSDNer,可以散了。
对你来说是基础的,对别人来说未必是基础的 [/quote] 那你倒是解释一下你的ID,oracle perl,这是一个不懂电脑的小白能想到的?而且在CSDN已有3年,3年啊,哪怕新生儿都上幼儿园了。
m0_54791314 2021-01-21
  • 打赏
  • 举报
回复
%f改为%.1f
霸气浩爷 2021-01-20
  • 打赏
  • 举报
回复
好厉害👍,真心都大神!
qq_34211258 2021-01-20
  • 打赏
  • 举报
回复
厉害了,不知道是咋回事
qq_1113502097 2021-01-20
  • 打赏
  • 举报
回复
不管你怎么输入,都不会输出0.125那么大的精度偏差。 出现精度偏差的原因是因为计算机存储的是二进制,当你定义一个数值之后,计算机会自动转换成二进制对象,对于整数部分处理起来比较简单,二进制 可以表示出可表示范围内的所有整数,但是小数点以下部分就比较难了。比如0.5可以用2的负1次方。即.1;0.25比如0.5可以用2的负2次方,即.01;0.75比如0.5可以用2的负1次方+可以用2的负2次方,即.11。(这里只是表述一个小数,实际上小数点也会被转换成一个二进制,即一个double或者long型对象,会有相应位数表示正负和小数点的位置。),因此小数部分的表达公式是,进制数乘以该位置的负指数次之后。例如一个二进制.101=1*2^-1+0*2^-2+1*2^-3。 如果你数学足够好,你就会发现,二进制可以表示成唯一的一个十进制数,但是并不是所有十进制数都可以用二进制表示出来,但是可以不断地去用二进制进行逼近。因此在精度范围内,两者输出是一致的。但是如果超过了精度范围,你就会发现两者出现不一致。这个误差是由于设计程序语言设计之初就导致的误差,是系统误差。因此我们在进行一个高精度计算时(或者在进行金融相关的计算与数据存储时候),并不会使用int、long、double这些数据类型,而是使用BigDecimal。
真相重于对错 2021-01-20
  • 打赏
  • 举报
回复
引用 32 楼 oracleperl 的回复:
[quote=引用 22 楼 lin5161678 的回复:][quote=引用 13 楼 oracleperl 的回复:] i请教这句"作为常识,大多数十进制有限位小数不能精确转换为二进制。“ 该怎么理解?
因为 十进制不是2的次幂 所以 有的十进制小数无法用二进制精确表示 如果是 八进制小数 十六进制小数 那么 取值范围之内 就都能精确的用二进制表示[/quote] 说不通啊,举个例子? 我现在想打印给float赋值123.99 然后就错了?理由是十进制没法转成二进制? 那么计算机还有什么用?我们还敢写程序吗?比如工资计算程序,就算错了? [/quote] 工资本来也不是按浮点处理的,
引用 47 楼 oracleperl 的回复:
[quote=引用 44 楼 zlzfc 的回复:]printf("result is=%.2f\n", 123456.99f); 就可以了
谢谢。这样我知道可以,但我不知道为什么那样是错的 我看了书《深入理解计算机系统》,说只有2的N次方的进制之间的转换才能确保一致 书上说 float32位,尾数24位,假设4个bits表示一个十进制数字,难道6个4位不能表示123.99吗? [/quote] 你把123.99转为2进制表示就知道了
lin5161678 2021-01-20
  • 打赏
  • 举报
回复
引用 47 楼 oracleperl 的回复:
[quote=引用 44 楼 zlzfc 的回复:]printf("result is=%.2f\n", 123456.99f); 就可以了
谢谢。这样我知道可以,但我不知道为什么那样是错的 我看了书《深入理解计算机系统》,说只有2的N次方的进制之间的转换才能确保一致 书上说 float32位,尾数24位,假设4个bits表示一个十进制数字,难道6个4位不能表示123.99吗? [/quote]不停说话是没用的 这东西能实践 0.2611 十进制 转换为二进制小数 写出来 转换过程 转换结果都"写"出来 自己实际操作一次 就什么都明白了 来吧干活
oracleperl 2021-01-20
  • 打赏
  • 举报
回复
引用 44 楼 zlzfc 的回复:
printf("result is=%.2f\n", 123456.99f); 就可以了
谢谢。这样我知道可以,但我不知道为什么那样是错的 我看了书《深入理解计算机系统》,说只有2的N次方的进制之间的转换才能确保一致 书上说 float32位,尾数24位,假设4个bits表示一个十进制数字,难道6个4位不能表示123.99吗?
oracleperl 2021-01-20
  • 打赏
  • 举报
回复
引用 45 楼 青蛙工作室 的回复:
严重怀疑楼主是来钓鱼提升CSDN的活跃度的,这么一个基础的问题纠缠了5页,而且看楼主的ID,oracle、perl,3年码龄,根本就不像一个刚接触计算机的小白。各位热心的CSDNer,可以散了。
对你来说是基础的,对别人来说未必是基础的
青蛙工作室 2021-01-20
  • 打赏
  • 举报
回复
严重怀疑楼主是来钓鱼提升CSDN的活跃度的,这么一个基础的问题纠缠了5页,而且看楼主的ID,oracle、perl,3年码龄,根本就不像一个刚接触计算机的小白。各位热心的CSDNer,可以散了。
oracleperl 2021-01-20
  • 打赏
  • 举报
回复
引用
赵老师好 请教下 1. 如果是整数,二进制和十进制互转没有问题对吧? 2.二进制转十进制也是可以精确转的对吧?,比如如下演算 二进制0.1111= 1*(1/2)+1*(1/4)+(1/8)+1/16= 7/8 3. 十进制小数转二进制就不一定能精确转了对吧?似乎是二进制没法记录10进制的所有值 或者说二进制的数值是十进制数值的子集?我这样理解对吧? 但我还没搞明白十进制转二进制的原理
forever74 2021-01-19
  • 打赏
  • 举报
回复
引用 25 楼 oracleperl 的回复:
[quote=引用 21 楼 真相重于对错 的回复:][quote=引用 20 楼 oracleperl 的回复:][quote=引用 17 楼 真相重于对错 的回复:]从数学的角度讲,数是无限的,而计算机只能表示有限的数,就算整形也受到位数的限制,内存的容量不管多大,也有尽头。而数是无限的。因此计算机无法表示所有的数。这个并不是计算机无用。。
谢谢赵老师,这个我能理解 但是为什么printf("result is=%f\n",123.99f); 这么小的一个十进制数,printf不能返回正确的值? 难道这个123.99转二进制也会转错?这是我不理解的。 [/quote] 你要了解为什么会转错,那么先要了解,计算机中如何存储整数,进而了解计算机中如何存储小数。了解这些就没有疑惑,不了解这些,别人也没法讲清楚。[/quote] 大神,别人没法讲清楚的事,包括书籍,C标准文档,都是“别人” 那么我如何了解清楚呢?[/quote] 这个梗不错,有开心麻花的范儿。
加载更多回复(42)
Linux系统提供了各种系统调用API用于进程之间的通信:    无名管道PIPE    命名管道FIFO    消息队列    共享内存    信号量    文件锁    信号signal....其中还包括system V和POSIX 两种接口标准,除此之外,Linux系统自身还扩展了自己的一套API接口用于进程间通信,比如signalfd、timerfd、eventfd等。本视频教程为《Linux系统编程》第05期,本期课程将会带领大家学习Linux下将近15种进程间通信IPC工具的使用,了解它们的通信机制、编程实例、使用场景、内核中的实现以及各自的优缺点。本课程会提供PDF版本的PPT课件和代码,学员购买课程后可到课程主页自行下载嵌入式自学路线指导图:------------------------------------------------------------------------------------------------------                   《嵌入式工程师自我修养》嵌入式自学系列教程                                          作者:王利涛------------------------------------------------------------------------------------------------------一线嵌入式工程师精心打造,嵌入式学习路线六步走: 第 1 步:Linux三剑客零基础玩转Linux+UbuntuGit零基础实战:Linux开发技能标配vim从入门到精通基础篇:零基础学习vim基本命令vim从入门到精通定制篇:使用插件打造嵌入式开发IDEmakefile工程实践基础篇:从零开始一步一步写项目的Makefilemakefile工程实践第2季:使用Autotools自动生成Makefile软件调试基础理论printf打印技巧Linux内核日志与打印使用QEMU搭建u-boot+Linux+NFS嵌入式开发环境第 2 步:C语言嵌入式Linux高级编程第1期:C语言进阶学习路线指南第2期:计算机架构与ARM汇编程序设计第3期:程序的编译、链接和运行原理第4期:堆栈内存管理第6期:数据存储与指针第7期:嵌入式数据结构与Linux内核的OOP思想第8期:C语言的模块化编程第9期:CPU和操作系统入门      搞内核驱动开发、光会C语言是不行的!      你还需要学习的有很多,包括:计算机体系架构、ARM汇编、程序的编译链接运行原理、CPU和操作系统原理、堆栈内存管理、指针、linux内核中的面向对象思想、嵌入式系统架构、C语言的模块化编程.....第 3 步:Linux系统编程第00期:Linux系统编程入门第01期:揭开文件系统的神秘面纱第02期:文件I/O编程实战第03期:I/O缓存与内存映射第04期:打通进程与终端的任督二脉第05期:进程间通信-------------------we are here!‍    第 4 步:Linux内核编程‍    练乾坤大挪移,会不会九阳神功,是一道坎。搞驱动内核开发,懂不懂内核也是一道坎。第 5 步:嵌入式驱动开发    芯片原理、datasheet、硬件电路、调试手段、总线协议、内核机制、框架流程....第 6 步:项目实战    嵌入式、嵌入式人工智能、物联网、智能家居...

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧