码迷,mamicode.com
首页 > 其他好文 > 详细

今天的菜来了——考考你是不是真懂得什么是类型转换

时间:2014-06-11 21:54:16      阅读:289      评论:0      收藏:0      [点我收藏+]

标签:style   class   blog   code   java   http   

我们在写程序时,总是会自觉或不自觉地频繁用到类型转换,比如将整数转换为浮点数或反之。

今天的题目主要讨论基本类型的转换(但和普通的类型转换有所不同哦,详见后文),考考你是否真的理解了类型转换的本质。在面向对象系统中还会涉及类和接口的类型转换,但它们和基本类型的转换还是有区别的,今天暂时不考虑。

(本人博客中所有题目都是我原创的,仅此一家,不买也来看看啊)

 

开始了,请听题。

 

题目很简单,自己编写一个模拟double到long的强制类型转换实现。即实现如下效果但不能使用语言提供的强制类型转换功能:

long a_long = (long) a_double;

考虑到语言之间的差异,下面分别说明一下题目的详细要求。

 

1. 喜欢C语言的看这里

bubuko.com,布布扣
请编写一个函数get_int_from_float,其原型如下:

long get_int_from_double(double *)

该函数接受一个double指针类型的参数并返回其整数部分。

例如调用get_int_from_float(
5.2),返回5。

注意,对于非常大的数,例如1.5E100,其实际的整数部分(实际上它就是一个整数)应该是15后面跟99个0这个数,但这个数太大,即使是long型也表示不了。此时不得不对结果进行截断(没办法,客观上被限制了)。 已知条件:各类型的长度确定,int和float都是32位,long和double都是64位。其他已知条件见后文。 要求:见后文
bubuko.com,布布扣

 

 

2. Java或C#版

bubuko.com,布布扣
请编写一个方法或函数:getIntFromFloat,它具有一个double类型的参数,返回的是浮点数的整数部分。
其原型为:

long getIntFromFloat(double)

注意事项见C语言版。

已知条件:参数始终是有效的浮点数,不考虑NaN等情况。其他见后文
要求:见后文
bubuko.com,布布扣

 

3. 喜欢Javascript或其他脚本语言的看这里:

bubuko.com,布布扣
请编写一个函数getIntFromFloat,它接受一个浮点数,并返回该浮点数的整数部分。例如调用getIntFromFloat(5.2)则返回5

其原型为:

function getIntFromFloat(f)

注意事项见C语言版。
已知条件:参数始终是有效的浮点数,不考虑NaN、非数字类型等情况。其他见后文 要求:见后文
bubuko.com,布布扣

 

 

共同的已知条件:

1. 浮点数的储存格式(同时也是一个IEEE754浮点数的简介哦,对题目不感兴趣的也可以看看这个)

bubuko.com,布布扣
(1) 题目里的浮点数都是64位IEEE754双精度浮点数,它们具有如下位模式(由低位到高位):

第0~51位,共52位:小数位,或尾数位
第52~62,共11位:指数部分
第63位:符号位,0为正1为负

(2) 尾数的规范化:

与我们熟悉的十进制科学计数法类似,浮点数的小数不能随便写,必须是规范形式。规范形式就是整数部分为1的小数,例如1.1、1.01等,非规范形式的尾数必须先转成规范形式。

(下面都以2进制举例)

例如101.11需要先转成规范形式1.0111(相当于小数点左移了2位,即缩小了4倍)

规范化的好处是小数点位置固定了,不需要再额外花一些位来记录小数点在哪里了。

另一个衍生出来的好处是整数部分的1是完全固定的,所以可以不要,使其变成隐藏的默认位。即只要存储后面的0111即可,计算时,再将前面的1和.补上。

(3) 指数部分

指数部分也有讲究。

首先是尾数转成规范化以后需要调整指数部分的值,使得规范化前后整个数的值不变。

例如原来的101.11相当于101.11×2^0,尾数规范化为1.0111后,指数部分需要补上2才行,即1.0111×2^2

这跟十进制是一样的。例如123.45转成科学计数法后是1.2345×10^2。

另外一点是,指数部分不是直接存储的,实际存储的是原值减去一个“修正值”后的结果,对double来说,修正值是1023。计算时,将存储的值加上1023计算出真正的指数大小(计算结果按11位有符号数来对待)。

这一点会让很多人迷惑:为什么要这么规定这不是蛋疼吗!要说尾数规范化可以简化实现并节约一个实实在在的位出来,那指数的这个规定是为了什么呢?表示范围没有变大,也没有节省位数,更是增加了一步额外的计算,真是出力不讨好啊!

关于这一点,这里先卖个关子,我后面再另开一篇博文详细讨论浮点数的时候再来解释吧,嘿嘿。

---------------------------

好了,总结一下:

要将一个以位模式存储的double转换为我们能看懂的二进制科学计数法,需要先提取出符号位、指数和尾数部分,然后就可以将其写为下面的形式:

(+-) 1.尾数 × 2^(指数+1023)

关于浮点数的详细解释可参考维基百科(英文的。没办法,中文的写的太渣了)
http://en.wikipedia.org/wiki/Floating_point
bubuko.com,布布扣

 

2. 取得double的位模式

bubuko.com,布布扣
假设已有如下的实现,你在程序中可以使用它们来获取一个double的位模式:

long getDoubleBitPattern(double) // Java或C#

function getDoubleBitPattern(d) // JS等

long get_double_bit_pattern(double *) // C 注意:该方法或函数返回的long和原double具有相同的位模式(因此它们表示的是完全不同的2个值)
bubuko.com,布布扣

 

 

共同的要求:

不能使用任何系统或语言提供的类型转换功能,包括隐式转换。

 

 

---------------------------

呼~~~好了,have fun!

 

 

 

 

 

今天的菜来了——考考你是不是真懂得什么是类型转换,布布扣,bubuko.com

今天的菜来了——考考你是不是真懂得什么是类型转换

标签:style   class   blog   code   java   http   

原文地址:http://www.cnblogs.com/antineutrino/p/3772373.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!