在软件中,我们将实数表示为二进制浮点数。实际上,我们将实数表示为一个固定精度整数(有效数字)乘以 2 的幂。因此,我们无法精确表示“π”,但可以得到一个非常接近的近似值:3.141592653589793115997963468544185161590576171875。前 16 位数字是精确的。
您可以将 π 的近似值表示为 7074237752028440 乘以 2 的 -51 次方。用这种方式表示数字有点麻烦,所以我们使用十六进制浮点数表示法。
在十六进制浮点数表示法中,数字 1 表示为 0x1.0,数字 2 表示为 0x2.0。其工作原理与十进制数相同。不同之处在于,数值的一半表示为 0x0.8,而无限字符串 0xffffff……表示为 1。
让我们回到圆周率 (π)。我们将有效数字写成十六进制数 0x1921fb54442d18,并在第一位数字后插入一个句点:0x1.921fb54442d18。它是 [1,2) 范围内的一个数,具体来说是 0x1921fb54442d18 乘以 2 的 -52 次方。
为了得到数字 pi,我们需要乘以 2,我们在末尾附加“p+1”来实现:0x1.921fb54442d18p+1。
当然,你不需要手动计算这些。在现代 C++ 中,你只需这样做:
std :: print ( " Pi (十六进制): {:a} \n " , std :: numbers :: pi ) ;
如果您使用 64 位浮点数,那么您可以使用指数表示法从大约 -1.7976931348623157e+308 到 1.7976931348623157e308,其中 1.79769e308 表示 1.79769 乘以 10 的 308 次方。以十六进制表示法,最大值为 0x1.fffffffffffffp+1023。整数值 0x1ffffffffffffff 为 9007199254740991,最大值为 9007199254740991 乘以 2 的 1023-52 次方。
超出此范围的数字将用无穷大表示。事实上,我们的计算机有无穷大的概念。它们知道无穷大除以 1 等于 0。因此,在现代 C++ 中,以下代码将打印零。
双精度无穷大= std :: numeric_limits <双精度> ::无穷大( ) ; std :: print ( "零: {} \n " , 1 /无穷大) ;
你可能会惊讶地发现,如果输入的字符串值大于所能表示的最大值,你不会得到错误或无穷大的值。例如,字符串 1.7976931348623158e308 所表示的数字大于浮点类型所能表示的最大值,但它并非无穷大。以下 C++ 代码将打印“true”:
std :: print ( " { } \n " , 1.7976931348623158e308 == std :: numeric_limits < double > :: max ( ) ) ;
那么,用字符串表示的、映射到无穷大的最小数字是多少呢?让我们回到十六进制表示。
- 第二大的值是 0x1.ffffffffffffep+1023
- 最大值为0x1.fffffffffffffp+1023。
- 下一个最大值是 0x2.0p+1023。
- 两者的中点是0x1.fffffffffffff8p+1023。
默认情况下,我们总是四舍五入到最接近的值。因此,所有介于 0x1.ffffffffffffe8p+1023 和 0x1.ffffffffffffff8p+1023 之间的数字字符串都会舍入到 0x1.ffffffffffffffp+1023。如果您正好位于 0x1.ffffffffffffff8p+1023,那么我们会“四舍五入到最接近的偶数”,即 0x2.0p+1023。因此,数字 0x1.ffffffffffffff8p+1023 正好位于无限值的边界。
以十进制表示,该值为 179769313486231580793728971405303415079934132710037826936173778980444968292764750946649017977587207096330286416692887910946555547851940402630657488671505820 681908902000708383676273854845817711531764475730270069855571366959622842914819860834936475292719074168444365510704342711559699508093042880177904174497792.0。
如果将此字符串输入为数字常量,许多编译器(无论哪种编程语言)都会报错并拒绝它。任何稍小的数字字符串都可以。
原文: https://lemire.me/blog/2025/09/29/smallest-number-string-that-is-infinite/