Java 原始数据类型的计算:运算符重载(Operator Overload)和类型转换(Type Conversion)
原文阅读:《算法(第四版)》第一章 第一节:基础编程模型
有没有在面试的时候被问到:下面这几行代码的执行结果是什么?依据是什么?
System.out.println (5/3);
System.out.println ((double)(5/3));
System.out.println (5/3.0);
System.out.println (5.0/3.0);
System.out.println ((int)5/(double)3);
这个问题涉及到的概念有:运算符重载和类型转换。
对于原始数据类型如int, double, 运算符+, -, *, / 可以用于不同类型数据之间的计算: int + int, int + double, int / double,此为运算符重载的一种。
不同类型之间计算时,先转换成同一类型再进行计算,这就涉及到类型转换,关键是要搞清楚这“同一类型”如何界定。
让我们先来看一下原文作者提到的运算符原则:
The key property of these primitive operations is that, an operation involving values of a given type has a value of that type.
原始数据类型运算的一个关键特性是,参与运算的值是什么类型,其运算结果就是同一类型。
这里涉及到两种情况:
- 参与运算的值都是同一类型,如:
5 / 3 等同于 (int 5) / (int 3),参与运算的值都是 int, 所以其结果类型也应是 int.
5.0 / 3.0 等同于 (double 5) / (double 3), 参与运算的值都是 double, 其结果类型也是 double.
- 参与运算的值属于不同类型:如
5 / 3.0 等同于 (int 5) / (double 3.0), 其结果应该是多少?什么类型呢?
这里参与运算的值有两种类型:int 和 double。要以哪种类型作为运算结果的类型,这就需要依据类型转换原则了。在Java中会自动转换类型,除非显性指名。其转换规则为:
Numbers are automatically promoted to a more inclusive type if no information is lost.
自动转换为比自身表述范围大的类型。
具体细节请参见官方文档: docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.4
所以对于 (int 5) / (double 3.0), double 是 64 位 ,int 是 32 位,所以计算的时候会自动将 int 5 转换成 double 5.0, 然后再计算,所以结果便是 double 类型。
明白了输出类型是什么,现在我们再来看开头的问题的答案:
System.out.println (5/3); //1
System.out.println ((double)(5/3)); // 1.0
System.out.println (5/3.0); // 1.6666666666666667
System.out.println (5.0/3.0); // 1.6666666666666667
System.out.println ((int)5/(double)3); // 1.6666666666666667
新的问题又来了,为什么 5/3 的值是 1 而不是 2? 按常规的四舍五入,5/3~=1.66666..., 四舍五入后应为 2。这便是另外一个原则了:
casting to an int is truncation instead of rounding
至于为什么是粗鲁的截断而不是四舍五入,我还没有弄清楚,如果您知道请帮忙解释一下。我试过其他语言比如Python, 同样的行为,所以猜测也许是计算机语言的某种通用逻辑比如浮点数的特殊性(详见引申思考题),还是各高级语言互相学习达成某种程度的一致?
小结:
原始数据类型运算符重载和类型转换用到的三个原则:
1。参与运算的值是何类型,其运算结果也是该类型
2。自动类型转换时会转换为表述范围大的类型
3。从范围大的类型转换为 int 时会截断小数点后的位数,而非四舍五入。
引申:
上述的几个原则,多数编程语言通用,比如我试过python. 这类通用的原则掌握了便可融会贯通。
引申思考题:
在多数编程语言中,为什么 0.1 + 0.2 不等于 0.3?
在您的IDE中试一下,然后再读读这篇论文:docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
Java 原始数据类型的计算:运算符重载(Operator Overload)和类型转换(Type Conversion)的更多相关文章
- Java语言基础(五) Java原始数据类型的分类以及数据范围
Java原始数据类型的分类以及数据范围 1.基本数据类型分为:整型(byte, short, int, long),浮点型(float, double),字符型(char),布尔型(boolean) ...
- c++ 运算符重载operator
一般格式为: 函数类型 operator 运算符名称(形参列表){ 对运算符的重载 } 注意函数名是由operator和运算符组成.在上面的一般格式中,operator是关键字,是专门用于重载运算符函 ...
- Java 原始数据类型
如何记住 Java 中的原始数据类型? 画了一个图方便记忆:
- swfit:运算符重载 Operator Methods
Operator Methods Classes and structures can provide their own implementations of existing operators. ...
- Java原始数据类型
Java定义了八种基本类型的数据:byte,short,int,long,char,float,double和boolean. 基本类型通常被称为简单类型.这些基本类型可以分为四组: 整数 - 包括: ...
- c++ operator操作符的两种用法:重载和隐式类型转换,string转其他基本数据类型的简洁实现string_cast
C++中的operator主要有两个作用,一是操作符的重载,一是自定义对象类型的隐式转换.对于操作符的重载,许多人都不陌生,但是估计不少人都不太熟悉operator的第二种用法,即自定义对象类型的隐式 ...
- PoEduo - C++阶段班【Po学校】-Lesson03-5_运算符重载- 第7天
PoEduo - Lesson03-5_运算符重载- 第7天 复习前面的知识点 空类会自动生成哪些默认函数 6个默认函数 1 构造 2 析构 3 赋值 4 拷贝构造 5 oper ...
- 《Inside C#》笔记(十一) 运算符重载
运算符重载与之前的索引器类似,目的是为了让语言本身使用起来更方便直接,也是一种语法糖. 一 运算符重载(Operator Overloading) 运算符重载的存在,使得现有的各种运算符可以被重新定义 ...
- C/C++对Lu系统内置动态对象进行运算符重载
欢迎访问Lu程序设计 C/C++对Lu系统内置动态对象进行运算符重载 1 说明 要演示本文的例子,你必须下载Lu32脚本系统.本文的例子需要lu32.dll.lu32.lib.C格式的头文件lu32. ...
随机推荐
- 面向对象 "一"
1:面向对象不是所有情况都适用. 2面向对象编程 a:定义类 calss Foo: 注意顶一个类的时候首字母必须是大写 def (方法一)(self,bb) pass b:根据创建对象,创建和Foo实 ...
- linux中添加环境变量(python为例)
最近想用Django搭建个人博客,之前学了些python基础语法,准备边学习Django边实战操作.自己有一个阿里云服务器,用的centOS,自带的是python2.7版本,我直接安装了python3 ...
- C#知识整理笔记
这里简单介绍了一些常用的属性,以及一些术语的解释和举例说明,不太全面,希望读者多多补充. 1.重载:函数名相同,参数的个数或参数类型不同; public void MyDog(string s); p ...
- 【解题报告】VijosP1448校门外的树(困难版)
原题: 校门外有很多树,有苹果树,香蕉树,有会扔石头的,有可以吃掉补充体力的--如今学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现有两个操作:K=1,K=1,读入l.r ...
- MP3 信息读取
MP3 信息读取 运行环境:Window7 64bit,.NetFramework4.61,C# 7.0: 编者:乌龙哈里 2017-03-13 参考: MP3-wikipedia ID3v1 MPE ...
- 1590: [Usaco2008 Dec]Secret Message 秘密信息
1590: [Usaco2008 Dec]Secret Message 秘密信息 Time Limit: 5 Sec Memory Limit: 32 MBSubmit: 209 Solved: ...
- 菜鸟聊JavaScript中this
菜鸟聊this this在JavaScript中是一个比较头疼的问题,我现在以一枚菜鸟的观点结合代码简单的谈下JavaScript中的this指向问题. 1.例子1 function a() { va ...
- Java引领新生活
阅读邹欣老师的博客,谈谈你期望的师生关系是什么样的? 我觉得师生关系应当是亲密无间,课上老师讲解学生配合,课下师生交流启发思考. 你有什么技能(学习,棋类,球类,乐器,艺术,游戏,......)比大多 ...
- Omi v1.0震撼发布 - 令人窒息的Web组件化框架
原文链接--https://github.com/AlloyTeam/omi 写在前面 Omi框架经过几十个版本的迭代,越来越简便易用和强大. 经过周末的连续通宵加班加点,Omi v1.0版本终于问世 ...
- Eclipse 中svn 分支,主干 合并与同步:
Eclipse 中svn的合并与同步: 1. 从主干拉取到分支: 然后一直下一步,到完成就OK了. 2. 从分支代码合并到主干: 2.1.先将本地需要提交更新的代码提交更新到svn分支去 2.2. ...