float能精确表示的最大数字是多少

stream_sz 2011-08-18 09:26:22
这个文法有点失误,容我解释。现在限定这个最大数字为不带指数的整数,如123456789.

我的问题是,float的尾数为23位,加上隐含的一位整数位是24位。那么能精确表示的最大数字应该是2^24 - 1 = 16777215,
但是我将float变量赋予大于16777215的值22345678,为什么依然能精确输出这个值?
...全文
6655 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
wanghaoran618B 2012-12-02
  • 打赏
  • 举报
回复
2^128-2^104 我觉得是,2^(U+1)(1-2^(-p)) U=127, p=24,
stream_sz 2011-08-18
  • 打赏
  • 举报
回复
8楼的说的靠点边。
大家可能都没理解我的意思,其实我说的就是精度,不是范围。我以整数为例,来说明这个问题。精度6到7位的说法过于含糊,请看我的分析,请根据我的分析来说明:

我的问题是,float的尾数为23位,加上隐含的一位整数位是24位。那么能精确表示的最大数字应该是2^24 - 1 = 16777215,
但是我将float变量赋予大于16777215的值22345678,为什么依然能精确输出这个值?
赵4老师 2011-08-18
  • 打赏
  • 举报
回复 2
C:\Program Files\Microsoft Visual Studio\VC98\Include\FLOAT.H
...
#define DBL_DIG 15 /* # of decimal digits of precision */
#define DBL_EPSILON 2.2204460492503131e-016 /* smallest such that 1.0+DBL_EPSILON != 1.0 */
#define DBL_MANT_DIG 53 /* # of bits in mantissa */
#define DBL_MAX 1.7976931348623158e+308 /* max value */
#define DBL_MAX_10_EXP 308 /* max decimal exponent */
#define DBL_MAX_EXP 1024 /* max binary exponent */
#define DBL_MIN 2.2250738585072014e-308 /* min positive value */
#define DBL_MIN_10_EXP (-307) /* min decimal exponent */
#define DBL_MIN_EXP (-1021) /* min binary exponent */
#define _DBL_RADIX 2 /* exponent radix */
#define _DBL_ROUNDS 1 /* addition rounding: near */

#define FLT_DIG 6 /* # of decimal digits of precision */
#define FLT_EPSILON 1.192092896e-07F /* smallest such that 1.0+FLT_EPSILON != 1.0 */
#define FLT_GUARD 0
#define FLT_MANT_DIG 24 /* # of bits in mantissa */
#define FLT_MAX 3.402823466e+38F /* max value */
#define FLT_MAX_10_EXP 38 /* max decimal exponent */
#define FLT_MAX_EXP 128 /* max binary exponent */
#define FLT_MIN 1.175494351e-38F /* min positive value */
#define FLT_MIN_10_EXP (-37) /* min decimal exponent */
#define FLT_MIN_EXP (-125) /* min binary exponent */
#define FLT_NORMALIZE 0
#define FLT_RADIX 2 /* exponent radix */
#define FLT_ROUNDS 1 /* addition rounding: near */
...
maquan 2011-08-18
  • 打赏
  • 举报
回复
因为楼主提的这个问题,我去学习了一下“浮点表示法”,又扫除了一个知识盲点。所以先得感谢楼主提出了一个好问题! ^_^

学是学了,现在还没完全搞明白。只是有这样一个猜想,供批判:

如果 float 值在内存中的 4 个字节是 0x4bffffff 的话,其表示的值为 33554430,比楼主给出的那个值还大,是不是这个才算是“float能精确表示的最大数字”?但是我觉得问题在于,0 - 33554430之间的数,并不一定都能“精确表示”,也许这就是关键。


————————————————————————————————
基于CSDN论坛提供的插件扩展功能,自己做了个签名档工具,分享给大家,欢迎技术交流 :)
jijididi 2011-08-18
  • 打赏
  • 举报
回复
它是浮点数,不能按照整型数表示范围的算法来表示的。
a375255194 2011-08-18
  • 打赏
  • 举报
回复
numeric_limits<float>::max(),得到的结果 ,3.40282e+038 ,你给的那个数字显然是可以表示的.
光阶码就有8个位了.
ayanamiyf 2011-08-18
  • 打赏
  • 举报
回复
精确度和存储范围不是一个概念

虽然存储范围很大,不过是用科学计数法来表示的,类似1.2 * 10 ^ -38 ----- 3.5 * 10 ^38,
而精确度表示的是能精确表示的位数,一般指有效数字,如:
1.2 * 10 ^ -38
虽然数很大,但精确度只有两位有效数字
ayanamiyf 2011-08-18
  • 打赏
  • 举报
回复
精确度和存储范围不是一个概念

虽然存储范围很大,不过是用科学计数法来表示的,类似1.2 * 10 ^ -38 ----- 3.5 * 10 ^38,
而精确度表示的是能精确表示的位数,一般指有效数字,如:
1.2 * 10 ^ -38
虽然数很大,但精确度只有两位有效数字
机智的呆呆 2011-08-18
  • 打赏
  • 举报
回复
float的指数-127最大是128啊,虽然float的尾数为23位,但指数为128时,小数点早跑到23位以外了,最大值2^128-1
机智的呆呆 2011-08-18
  • 打赏
  • 举报
回复
float的指数-127最大是128啊,虽然float的尾数为23位,但指数为128时,小数点早跑到23位以外了,最大值2^128-1
  • 打赏
  • 举报
回复
先转化成科学计数法,精度是小数点后6-7位。
maquan 2011-08-18
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 stream_sz 的回复:]
8楼的说的靠点边。
大家可能都没理解我的意思,其实我说的就是精度,不是范围。我以整数为例,来说明这个问题。精度6到7位的说法过于含糊,请看我的分析,请根据我的分析来说明:
我的问题是,float的尾数为23位,加上隐含的一位整数位是24位。那么能精确表示的最大数字应该是2^24 - 1 = 16777215,
但是我将float变量赋予大于16777215的值22345678,为什么依然能精确输出这个值?[/Quote]
我的理解是,这个 22345678 虽然没有产生舍入误差,但并不能算是“精确表示”,只是“碰巧误差为零”而已,只要大于 16777215 的值都不能算精确表示。

或者更准确一点说:凡是表达为二进制后有效数字多于 24 位的数值,都不能精确表示,但其中“第一个 1 和最后一个 1 的距离不大于 24”的那些,则恰好舍入误差为零。


————————————————————————————————
基于CSDN论坛提供的插件扩展功能,自己做了个签名档工具,分享给大家,欢迎技术交流 :)
AndyZhang 2011-08-18
  • 打赏
  • 举报
回复
4个字节,32位,再看看IEE 中浮点数的表示方法,不同的表示方法范围不一样。
icemornings 2011-08-18
  • 打赏
  • 举报
回复 1
根据IEEE浮点数表示法:
V = (-1)^s * M * 2^E.
其中s为符号位,M为尾数,E是阶码。
---------------------------------------
现在你是想找出浮点表示法不能精确表示的正整数是吧。
我们来观察IEEE表示法:
首先排除非规格化的值,因为非规格化的值只能表示<1的数。
再来看规格化的值(位方便讨论,不考虑符号位):
M * 2^E相当于对M进行移位处理,移位处理是不会增加1的个数的
因此我们需要的这个整数的第一个1到最后一个1的距离必须大于M首尾的距离
假设有n个尾数位(M = 1 + n个尾数位所表示的小数),那么这个最小的整数值就是10000(n个0)1,也就是2^(n + 1) + 1.
------------------------------
综上所述,IEEE表示法不能精确表示的正整数有以下特点:
首尾两个1的距离大于(n+1)。
---------------------------------------
我们再来看你给的那个数字
22345678 = 1010101001111011111001110.
很明显这个数字可以这样分解:
M = 1 + 0.01010100111101111100111
E = 24
V = M * 2^E
因为首尾两个1之间的距离等于24,而不是大于24.
hongwenjun 2011-08-18
  • 打赏
  • 举报
回复
没必要太纠结了,怕越界 就用 double
效率不会差,可能还会更加好
icemornings 2011-08-18
  • 打赏
  • 举报
回复
假设float用32位来存储,1个符号位,8个阶码位,23个尾数。
那么float不能精确表示的最小整数是2^24 + 1 = 16777217.0F,而不是2^24 - 1.
ForestDB 2011-08-18
  • 打赏
  • 举报
回复
LZ知道科学计数法么?
有没有去看22345678存成什么样子了?
是你想的那样的么?

推荐看IEEE 754标准,推荐debug。

69,371

社区成员

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

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