干将莫邪的故事--java比较操作注意要点

干将莫邪的故事--java比较操作注意要点
2021年08月12日15:13:59 0 381

干将莫邪的故事--java比较操作注意要点

 

故事背景

《搜神记》:

干将莫邪的故事--java比较操作注意要点

 

楚干将、莫邪为楚王作剑,三年乃成。王怒,欲杀之。剑有雌雄。其妻重身当产。夫语妻曰:吾为王作剑,三年乃成。王怒,往必杀我。汝若生子是男,大,告之曰:‘出户望南山,松生石上,剑在其背。’于是即将雌剑往见楚王。王大怒,使相之:剑有二,一雄一雌,雌来雄不来。王怒,即杀之。

莫邪子名赤,比后壮,乃问其母曰:吾父所在?母曰:汝父为楚王作剑,三年乃成。王怒杀之。去时嘱我:‘语汝子,出户望南山,松生石上,剑在其背。’于是子出户南望,不见有山,但睹(dû)堂前松柱下石低之上。即以斧破其背,得剑,日夜思欲报楚王。

王梦见一儿,眉间广尺,言欲报仇。王即购之千金。儿闻之,亡去,入山行歌。客有逢者,谓:子年少,何哭之甚悲耶(yé)?曰:吾干将、莫邪子也,楚王杀吾父,吾欲报之!客曰:闻王购子头千金,将子头与剑来,为子报之。儿曰:幸甚!即自刎(wên),两手捧头及剑奉之,立僵。客曰:不负子也。于是尸乃仆。

客持头往见楚王,王大喜。客曰:此乃勇士头也,当于汤镬(huò)煮之。王如其言。煮头三日三夕,不烂,头踔出汤中,瞋目大怒。客曰:此儿头不烂,愿王自往临视之,是必烂也。王即临之。客以剑拟王,王头随坠汤中,客亦自拟己头,头复坠汤中。三首俱烂,不可识辨。乃分其汤肉葬之,故通名三王墓,今在汝南北宜春县界。

java中的雌雄双剑0与-0

干将莫邪的故事--java比较操作注意要点

 

0与-0按理说都是一样的,但在程序中不一定就相等哦。请看下面的程序:

public static void main(String[] args) {
System.out.println(Float.compare(-0.0f, 0.0f));
System.out.println(Math.max(-0.0f, 0.0f));
System.out.println(Math.min(-0.0f, 0.0));
System.out.println(-0.0f<0.0f);
System.out.println(-0.0f<=0.0f);
}

上面的结果可能让你大吃一惊。

-1
0.0
-0.0
false
true

让我们看看JSL上怎么说吧

15.20.1. Numerical Comparison Operators <, <=, >, and >=
The type of each of the operands of a numerical comparison operator must be a type that is convertible (§5.1.8) to a primitive numeric type, or a compile-time error occurs.
Binary numeric promotion is performed on the operands (§5.6.2).
Note that binary numeric promotion performs value set conversion (§5.1.13) and may perform unboxing conversion (§5.1.8).
If the promoted type of the operands is int or long, then signed integer comparison is performed.
If the promoted type is float or double, then floating-point comparison is performed.
Comparison is carried out accurately on floating-point values, no matter what value sets their representing values were drawn from.
The result of a floating-point comparison, as determined by the specification of the IEEE 754 standard, is:
If either operand is NaN, then the result is false.
All values other than NaN are ordered, with negative infinity less than all finite values, and positive infinity greater than all finite values.
Positive zero and negative zero are considered equal.
For example, -0.0<0.0 is false, but -0.0<=0.0 is true.
Note, however, that the methods Math.min and Math.max treat negative zero as being strictly smaller than positive zero.
Subject to these considerations for floating-point numbers, the following rules then hold for integer operands or for floating-point operands other than NaN:
The value produced by the < operator is true if the value of the left-hand operand is less than the value of the right-hand operand, and otherwise is false.
The value produced by the <= operator is true if the value of the left-hand operand is less than or equal to the value of the right-hand operand, and otherwise is false.
The value produced by the > operator is true if the value of the left-hand operand is greater than the value of the right-hand operand, and otherwise is false.
The value produced by the >= operator is true if the value of the left-hand operand is greater than or equal to the value of the right-hand operand, and otherwise is false.

干将莫邪的故事--java比较操作注意要点

 

Positive zero and negative zero are considered equal.(浮点数中0.0和-0.0进行关系比较是相等的)

For example, -0.0<0.0 is false, but -0.0<=0.0 is true.(例如:-0.0<0.0是false,但-0.0<=0.0 是true)

Note, however, that the methods Math.min and Math.max treat negative zero as being strictly smaller than positive zero.(主意:然而,使用Math.min和Math.max进行浮点数比较时,-0.0时小于0.0的)

java中浮点数在循环中使用要慎重

public static void main(String[] args) {
final int START = 2000000000;
int count = 0;
for (float f = START; f < START + 50; f++)
count++;
System.out.println(count);
}

f的初始值接近于Integer.MAX_VALUE,因此它需要用31 位来精确表示,而float 类型只能提供24 位的精度。对如此巨大的一个float 数值进行增量操作将不会改变其值。因此,这个程序看起来应该无限地循环下去,因为f 永远也不可能解决其终止值。但是,如果你运行该程序,就会发现它并没有无限循环下去,事实上,它立即就终止了,并打印出0。怎么回事呢?

问题在于终止条件测试失败了,其方式与增量操作失败的方式非常相似。这个循环只有在循环索引f 比(float)(START + 50)小的情况下才运行。在将一个int与一个float 进行比较时,会自动执行从int 到float 的提升[JLS 15.20.1]。遗憾的是,这种提升是会导致精度丢失的三种拓宽原始类型转换的一种[JLS5.1.2]。(另外两个是从long 到float 和从long 到double。)

f 的初始值太大了,以至于在对其加上50,然后将结果转型为float 时,所产生的数值等于直接将f 转换成float 的数值。换句话说,(float)2000000000 ==2000000050,因此表达式f < START + 50 即使是在循环体第一次执行之前就是false,所以,循环体也就永远的不到机会去运行。

总结

数据比较的时候,尽量避开浮点数,使用int,long等。

 

打赏 点赞(0)
weinxin
投诉建议
文章名+链接地址,发送到此微信:tourism52
css,常见,样式,命名,规则,css,常见,样式,命名, 菜鸟教程

css常见样式命名规则

css常见样式命名规则 前言 也许你曾经看到过很多样式命名规则,也参考了我们制定的命名规范,但是大部分的具体样式还是不知道如何命名,主要思想或者标准是什么,也就是前面.m-pane...
SQLite,的,使用,SQLite,的,使用,什么,是,是一,款, 菜鸟教程

SQLite的使用

SQLite的使用 什么是SQLite SQLite是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中。它实现自给自足的、无服务器的、零配置的、事...
机器,学习,简明教程,线性,回归,算法 菜鸟教程

机器学习简明教程4-线性回归算法

本节我们会认识第一个机器学习算法——线性回归算法(Linear Regression),它是机器学习算法中较为简单,且容易理解的算法模型,大家可以把它看做是机器学习的第一个“Hel...
个,高级,sql,语句,个,高级,sql,语句,问题,及, 菜鸟教程

50 个高级 sql 语句

50 个高级 sql 语句 问题及描述: --1.学生表 Student(SID,Sname,Sage,Ssex) --SID 学生编号,Sname 学生姓名,Sage 出生年月,...
基于缓存的存储器层次结构 菜鸟教程

基于缓存的存储器层次结构

存储技术:不同存储技术的访问时间差异很大。速度较快的技术每字节的成本要比速度较慢的技术高,而且容量小。 一种组织存储器系统的方法,成为存储器层次结构(memory hierarch...

评论列表 共有 0 条评论

暂无评论