在C的小数点数据类型中不能精确表示的最小值是什么?

j2cgzkjk  于 2023-05-28  发布在  其他
关注(0)|答案(3)|浏览(136)

例如:不能再精确表示为double的最小uint32_t值是多少?等等的。
如何计算这些值?

vi4fp9gy

vi4fp9gy1#

不能再精确表示为double的最小uint32_t值是多少?
所有uint32_t都可以精确地表示为double,因为C指定DBL_DIG >= 10导致C编码 * 精确 * 至少所有连续整数值[-1010到+1010]。这包括所有的uint32_t
如何计算这些值?
参见C规范。
可精确编码为浮点类型的整数值的最小连续范围由C主要通过以下方式指定:

FLT_DIG 6
DBL_DIG 10
LDBL_DIG 10

float的情况下,所有6个十进制数字整数都可以表示[-999,999.0到+999,999.0],包括+/-1,000,000。从零开始向下,第一个不能表示为float的负整数值是-1,000,001。这是FLT_RADIX == 10时的最小范围,几乎不再存在。
FLT_RADIX == 2(非常常见)时,有效位中的二进制位数p为:

(p-1)*log10(2) >= xxx_DIG

floatp求解该方程至少为20。使用p == 20float可以精确地编码整数[-220到+220]或[-1,048,576到+1,048,576]。
最低规格也就这么多了。

常用限额

典型的float具有符号位和24个二进制数字,其范围比C规范的最小值更宽。它精确地编码整数[-224到+224]。第一个不可表示的负整数值:-224-1或-16777217。

ua4mk5z4

ua4mk5z42#

floatdouble是什么取决于编译器,它基于体系结构进行选择。在x86或x86-64上,float可能是IEEE单精度浮点数,double可能是IEEE双精度浮点数。
| 类型|连续范围可表示整数(包含边界)|此范围的大小|
| - -----|- -----|- -----|
| uint16_t| 0 .. 2^16-1| 2^16|
| uint32_t| 0 .. 2^32-1| 2^32|
| uint64_t| 0 .. 2^64-1| 2^64|
| IEEE单精度|-2^24 .. 2^24| 2^25+1|
| IEEE双精度|-2^53 .. 2^53| 2^54+1|
IEEE单精度浮点数有24位精度[1],它可以精确地表示比上面提到的大得多的数字,但它不能精确地表示2^24+1或-2^24-1。
IEEE双精度浮点数有53位的精度[1],它可以精确地表示比上面提到的大得多的数字,但它不能精确地表示2^53+1或-2^53-1。
1.次法线(极小的数字)的精度较低。

tf7tbtn2

tf7tbtn23#

1.你的问题中有一个主要的矛盾:你说的是“小数点”数据类型,但后来提到了“双精度”。
double,在绝大多数可用的实现中,不是小数点类型,而是二进制点类型(IEEE 754 64位十进制)。你可以在互联网和文献中更详细地了解它们的区别。
下面我将假设二进制double,而不是(实际上很少出现和使用)真正的十进制类型。
2.这很简单,但有点棘手:))
我将假设您引用的平台本机实现IEEE 754,float是32位二进制IEEE数,double是64位二进制IEEE数。在这种情况下,float有24位尾数,前导为1(我们在这里不计算非正规值),我们需要最小的值,* 不包括前导尾随零 *,不适合24位。(无需检查问题的指数范围。)
对于以下内容,“0 b”是二进制前缀,并且“”是幂运算符。
16777215 = 2
24-1是0 b1111111111111111111111(24个连续的1)。很合适。
16777216 = 224是0 b1000000000000000000000(1和24个连续的0)。很合适。
16777217 = 2
24+1是0 b10000000000000000000001(1,23个连续的0和1)。它不合适。
“浮动”可以表示:...,16777214,16777215,16777216,16777218,16777220,16777222...因此,从16777216 = 2**24开始,可表示值之间的步长为2。
因此,最小的无符号整数,不能用“float”表示,是16777217。
在其他情况下,不需要复制所有这些长字符串位-使用具有53位尾数的double,这将是非常麻烦的。我希望这个原则能够得到很好的体现。对于您的具体示例,这意味着任何uint32_t值都可以在double中精确表示,但不能在float中表示。
3.此外,对于uint32_tdouble,您可以只检查声明的准确性。uint32_t最多为10位十进制数字(保证为9位)。double最多需要17位十进制数字来精确表示任何值,并且保证在其中表示15位。范围之间存在明显差异,因此无需进行更精确的边界检查。

相关问题