Java放弃了可移植浮点的哪方面?
Java是以“编写一次,随处运行”为口号发布的;而它的采用可能更多的是为了“现在我们有了一种语言,可以在熟悉的工作流中提供垃圾收集,并具有良好的标准库”,
解答动态
中间结果的范围。
Java语言规范,第2版。通过引入“FP strict”表达式的概念,放宽了浮点表达式的求值规则,定义如下(§15.4,p.319):
在FP strict表达式中,所有中间值必须是浮点值集或双值集的元素,这意味着所有FP strict表达式的结果必须是ieee754算术对使用单格式和双格式表示的操作数所预测的结果。在非FP严格的表达式中,允许实现使用扩展的指数范围来表示中间结果;粗略地说,净效果,在单独使用浮点值集或双值集可能导致溢出或下溢的情况下,计算可能会产生“正确答案”。
实际语义在§5.1.8“值集转换”中有详细说明;这两个部分将在其他部分中引用,这些部分指定规范所考虑的“中间”浮点结果(基本上归结为所有算术运算,但不是变量赋值或参数传递)。
fp strict模式可以通过strictfp关键字启用,该关键字可以应用于类(JLS第2版,§8.1.1.3)、方法(§8.4.3.5)和接口(§9.1.1.2)。
此定义在Java 15中一直保持不变(分别为JLS 15、§15.4和§5.1.13)。在第一版中,没有这样的“严格性”概念,因此所有浮点表达式都是隐式严格的。
这与C语言的问题基本相同(参见GCC臭名昭著的bug 323和GCC手册中的“失望”部分);尽管在Java中,由于规范只允许JVM实现扩展指数范围,并要求在变量赋值(JLS第2版§5.2)和参数传递(§5.3)时严格将值四舍五入到它们的标称类型,因此这一点的影响要小得多。
@超级跑车他的回答更详细地说明了动机;这也让我意识到我对规范有点误读。
据我所知,除非情况有所改变,否则我认为即使在非严格模式下,Java也要求浮点值在尾数中舍入到适当的长度。但是,允许留有余地,其值小于最小标准化浮点值。大多数浮点值应具有24位精度,但幅度在最小标准化值的0.5到1.0倍之间的值应具有23位,幅度在最小标准化值的0.25到0.5倍之间的值应具有22位,等等。许多硬件平台都有将尾数快速舍入到24位的方法,但是除了将一个值以浮点形式存储到内存中,然后将其读回外,无法有效地强制进行与大小相关的舍入。
如果语言提供不同的浮点类型,这些浮点类型具有匹配的表示形式,但语义不同,那么围绕这些问题的许多争议是可以避免的,以及一种指定哪个特定类型应该由float或double等关键字表示的方法。如果希望通用实现提供显式选择语言默认行为的模式,以及使用最有效行为的模式,然后,希望编写在各种平台上高效但正确运行的代码的人可以使用在他们的平台上运行效率更高的模式和在他们的平台上运行效率更低但会模仿其他平台行为的模式来测试他们的代码。不幸的是,尽管不同的行为对于不同的平台和目的更有用,但通常的趋势是试图推动所有实现以相同的方式处理所有事情。- End
免责声明:
本页内容仅代表作者本人意见,若因此产生任何纠纷由作者本人负责,概与琴岛网公司无关。本页内容仅供参考,请您根据自身实际情况谨慎操作。尤其涉及您或第三方利益等事项,请咨询专业人士处理。