Java 十六进制浮点字面量歧义

Java Hexadecimal Floating Point Literal Ambiguity

在Javaspecification中,它表示如下:

For hexadecimal floating-point literals, at least one digit is required (in either the whole number or the fraction part), and the exponent is mandatory, and the float type suffix is optional. The exponent is indicated by the ASCII letter p or P followed by an optionally signed integer.

据我了解,指示字母的指数必须是 p 或 P 才能解决与十六进制数字 e 或 E 的歧义。为什么在使用时说指示类型的后缀(float vs double)是可选的它会引入字母 d、D、f、F 的歧义,这些字母也是十六进制数字?

根据 grammar:

DecimalFloatingPointLiteral:
  Digits . [Digits] [ExponentPart] [FloatTypeSuffix] 
  . Digits [ExponentPart] [FloatTypeSuffix] 
  Digits ExponentPart [FloatTypeSuffix] 
  Digits [ExponentPart] FloatTypeSuffix

HexadecimalFloatingPointLiteral:
  HexSignificand BinaryExponent [FloatTypeSuffix]

可选的 FloatTypeSuffix 必须 遵循十六进制浮点数的强制性 BinaryExponent

如果您添加 fd 而没有 BinaryExponent,则它是十进制浮点数。

十六进制形式是为了使尾数精确。指数是一个整数,可以精确地表示为小数,因此不会与字母 d 或 f 冲突。

规范化浮点数的形式是

sign * 1.mantissa * 2 ^ exponent

如果您查看这些示例,预计在准确指定尾数时使用十六进制表示法。

// from java.lang.Double

public static final double MAX_VALUE = 0x1.fffffffffffffP+1023; // 1.7976931348623157e+308

public static final double MIN_NORMAL = 0x1.0p-1022; // 2.2250738585072014E-308

public static final double MIN_VALUE = 0x0.0000000000001P-1022; // 4.9e-324

在这个表格中很容易看到预期的尾数和指数。虽然其他形式也是可能的,但它们并不那么清晰。