Floating Point学习笔记

Post on by michaelyin

写代码的时候发现对Float的原理和使用方式没有一个系统的理解,找了资料学习后将知识点在这里进行整理

Float存储原理:

提到Float的存储方式首先必须提一下IEEE 754这个标准,该标准的出现主要解决了不同计算机之间浮点数表示方式和计算方式无法兼容的问题,现在的计算机内的浮点数的存储方式都是支持这个标准的。

一个浮点数主要由三部分组成:$$V = (-1)\^{s}\\times M\\times 2\^{E}$$

s表示浮点数的正负

M表示小数部分

E是2的指数,用来表示2的乘方

如果将这三部分对应到存储的bit位上去,那么s对应一个bit位,用来表示浮点数的正负,k个bit位用来表示表示2的乘方,这k个bit位统一用exp来表示,n个bit位用来表示小数部分,统一用fra来表示

image

现在已经知道浮点数的存储位一共有三部分组成,而浮点数本身也被分成了三种类型,三种不同类型的存储方式都有其自身的特点

1:Normalized Values

这是最普通的情况,当exp部分的bit位不全为0和不全为1的时候,在这种情况下,exp部分的值E = e-Bias,这里e是exp部分的无符号整形值,$$Bias = 2\^{k-1}-1$$

frac表示小数部分的值,如果bit位的小数的值为f,frac部分的实际值M = f +1

2:Denormalized Values

当exp部分全为0的时候,这时候的浮点数就是Denormalized Values,exp对应的值E = 1- Bias,Bias的值和上面一样的定义

frac部分的实际值M = f(和前一种有区别,至于为什么后面会讲到)

Denormalized Values一个很重要的作用就是用来表示非常接近0的值

3:Special Values

当exp全部为0,frac全部为0的时候,根据s的值分别表示正无穷和负无穷大 ...


数组分割的一些错误解法

Post on by michaelyin

问题:有一个没有排序,元素个数为2N的正整数数组。要求把它分割为元素个数为N的两个数组,并使两个子数组的和最接近。

这个问题的正确解法前面一篇博文已经有写,这里主要是把错误的解法和原因进行一下分析。

天平法:

这种思路主要就是将2N数组进行排序,从大到小,然后从大到小进行排放,类似将砝码从大到小放到天平上,比如这篇博文猛击这里

点评:最后要的是两边差值最接近,和砝码本身的大小并无直接联系,这种解法很容易找到反例:

200 190 180 170 160 10

200 180 160 并不是最优解

差值法:

前面天平法的缺陷也给了我一点启示,如果是两个一组一起放到天平上的话,启示应该按照两个砝码的差值来进行拜访,排序不应该针对单个砝码,而应该针对砝码的差值

1:将砝码分成A,B两组

2:两组的砝码按照位置进行对应,比如A[0]和B[0]进行对应

3: 对应的A[0]和B[0]之间肯定是有差值的,针对差值的绝对值进行排序,按照从大到小

4: 针对差值进行“砝码”的摆放,调整A[i] B[i],保证差值总和的绝对值保持在最小

代码如下:

def test1(data):
    data = sorted(data ...

数组分割

Post on by michaelyin

最近在做Python Challenge的时候无意中发现了checkio这个练习PY的地方,题目不难,正好可以在工作之余修炼下PY功力。。

loading-cargo这个题目的意思比较简单 ,有一个无序、元素个数为2n的正整数数组,要求:如何能把这个数组分割为两个子数组,子数组的元素个数不限,并使两个子数组之和最接近

1:Solve

根据题目给出的Hint,可以使用暴力破解的方式穷举出所有可能的组合,并算出其和,使用PY提供的库可以很方便的做到,代码如下

import itertools

def checkio(data):
    total = sum(data)
    diff = total
    for i in range(1, len(data)):
        for value in itertools.combinations(data, i):
            diff_sub = sum(value)
            diff_sub = total - 2 * diff_sub
            if(diff_sub >= 0 and diff_sub < diff):
                diff = diff_sub
    return diff

2:Optimize

穷举解法并不是很优化的解法,因为其中需要穷举出所有的组合,然后根据组合算出分组的和,然后进行判断。

此题其实可以采用DP(动态规划)来解决 ...


更换邮箱那些事儿

Post on by michaelyin

由于中国雅虎的邮箱服务马上就要停止,趁着放假有时间,决定把散落各处的账号进行整理,并将原先和雅虎邮箱绑定的账号绑定到另外的邮箱上去,防止由于邮箱失效造成以后不能找回账号的登录密码。

更换登录账号绑定的邮箱,方便用户进行数据迁移,这是一个原始用户需求,各个应用对于这个需求有着不同的解决方案。

想到我的众多可爱师妹们,以及那些众多好图,人人账号是我最先进行修改的

1: 进入账号设置页面以后,看到有个修改账号功能,点开以后,直接囧了

7

2:修改个密码还要申诉,实在有点不太理解。没办法,那就申诉吧,结果接下来,我被深深的囧到了

8

3: 一个简单的功能,竟然被做的如此复杂,这一刻,我认定它的产品经理的头,被门夹了。。。

接着,是经常用来听歌的虾米网,更改邮箱后,能使用新的邮箱来登录了,不过在个人设置里面,个人邮箱竟然还是显示的是偶的雅虎邮箱地址。。。。汗。。。虾米网有测试人员么?

image

抛开这两个有硬伤的不谈,其他的产品,在修改邮箱上,主要是在一个地方有所不同:

假设用户原先使用的是邮箱A,现在想迁移到邮箱B,那么在迁移过程中,是否需要首先通过向邮箱A发送邮件进行认证?

豆瓣,CSDN,当当,是需要强制在邮箱A端通过链接认证的方式走流程的,姑且称为方案一

Apple, Evernote, 新浪微博,淘宝,支付宝,不需要在邮箱A进行认证,只需要在邮箱B进行认证即可,姑且称为方案二

众多应用在这点上的分歧其实是很有意思的:

从使用便捷性来说,由于方案二少了邮箱A的认证过程,所以整个切换过程显得很方便,使用感觉不错,而方案一略显繁琐,当用户对原有邮箱不能正常登陆时,用户会无比纠结,最终找客服进行申诉。

从安全性上来说,方案一似乎拥有更多的 ...


由老毛桃想到的

Post on by michaelyin

由于装Ubuntu 12.04的时候好像是由于硬盘参数不对导致无法安装,需要在进入系统前使用工具进行修复。不过哥的PC光驱已经不能正常弹出,除非使用大头针,更坑爹的是,上次搬家的时候把系统启动盘弄丢了。。。

然后再搜索能否通过硬盘的方式加载Windows PE系统,在百度给的相关搜索里面看到了老毛桃这个软件,进入网站看了一下以后,顿时觉得自己OUT了。。。

这个软件可以将常用的工具放到U盘中,在BIOS中配置好以后就能够通过U盘自动(猛击这里),效果和光盘启动是一样的,里面也带了各种常用的工具。对于一般的系统修复,检查来说,已经足够了。除此之外,这个软件提供了对ISO的处理,并能将ISO烧录到U盘中进行启动。省去了刻录光盘的繁琐。(ISO模式暂未亲测)

也正是因为这个软件,让我觉得以后买PC,光驱或许不是必选项了。。。回想前几年,基本只是在对系统进行引导启动的时候用一用光驱。

软件背后,让我反思的是我们看问题的思维。以前看起来理所当然的解决方案,放到现在未必就是最合理的,唯一能做的,就是不断地提高自己。