十进制小数转二进制,用Excel实现

不借助现成工具,亲身手动解决是加深对问题理解的不二法门。不过,有时候重复繁琐的步骤真是令人厌烦。这时既手动又自动的方法,是按手动的方法写个工具解决,而不借助现成的工具。

例如,十进制小数转二进制。(0.5)dec->(0.1)bin手动的方法在计算机导论、数字电路课里都有,这个方法的名字叫 乘2取整。课本里有,在此不赘述。

Excel 中没有函数可以输入十进制小数给出二进制。在这里,我们按手动解决的过程,用Excel求十进制小数的二进制。

1. 效果演示

其中第二行中的0.14是输入的十进制小数;

第三行是输出的二进制小数,每个单元格对应二进制小数的一位。

如果我们想换个十进制小数,例如 2.718,那么修改0.14为0.718,二进制小数的每一位会自动更新。

如果我们想要二进制小数点后更多位数,那么把最后一位的两列向右复制。

验算操作是 复制第三行(取整)中所有二进制小数位,在第五行(小数进制|验算)选择性粘贴为数值。

验算的过程在下图的最下面三行中。

验算结果在最底一行(转十进制)中,0.7179……,由于精度不足所以有误差。

通过第三方工具交叉检验,https://www.inchcalculator.com/decimal-to-binary-converter/,如下图所示与上述Excel工具的结果一致。

2. 公式

自行制作这个Excel的步骤很简单。

模仿课本里的手动方法,乘2、取整两步。

乘2 这一行,除第1个数即输入的十进制小数,
其余每个单元格的公式都类似“=IF(D2<1,D2,D2-1)*2”。

其中,D2是当前单元格左侧的那个单元格。

这个公式的含义是 把左侧的单元格乘2,即 乘2操作。稍微有点细节需要考虑,乘2取整法要求每次运算都舍去整数部分。在这里,考虑最大的小数为0.9,乘以2以后为1.8,因此整数部分不会大于1。进一步,整数部分只有两种可能,1或者0。如果整数部分为1,那么减1以后再乘以2;如果整数部分为0,那么把小数部分乘以2。

以上是 乘2 这一步。

取整这一步,每个单元格的公式都类似“=IF(E2<1,0,1)”。

其中,E2是当前单元格同一列上一行的那个单元格,即乘2以后的结果。

这个公式的含义是 如果乘2的结果小于1,那么整数部分为0;否则整数部分为1。

复制这一列的两个公式,粘贴到右边的每一列。粘贴列数的多少,取决于你希望有转换时精度达到何种程度。

验算有两个公式,即 按权相加 的两步。

其一是 求每一个二进制对应的十进制权重,所谓“按权”。

其二是 对所有位求和,所谓“相加”。

这样,就可以用Excel完成十进制纯小数转换为二进制了。任意小数的整数部分,可以单独手动处理,用计算器、Excel都容易完成。

3. 开发过程及考虑

初学程序设计,对编程思路不熟悉,或者对excel不熟悉,看了上面的公式可能会有挫败感。“你怎么一下子就把这些写出来了,我做不到啊。”

有人确实能做到,你做不到也不需要焦虑,我也做不到。我并非一步写出来的,过程如下。看了步骤你就会发现,我很笨,连我这么笨也能写出来,你当然也没有问题。

第1步

这里没有任何公式,只是把架子搭起来。你可能觉得,这有啥啊。反正我每次搭完架子,写完main函数,都要反复看一会儿,自矜半晌。这个架子提示我以后哪个变量要放在什么地方。右边的那些,不是截掉了,而是最初根本就没有,反正要用公式复制粘贴算出来的,现在写上,只是影响我的注意力,降低我的自信心而已。

第2步 乘2

啥东西乘2呢?所以,我要先写个十进制纯小数,并且先验地知道它的结果。位数还不能太少,不然检测不出bug。

就0.718吧,找个工具算一下。

在运行我写的每个程序以前,我对它的结果一定是有预期的。运行的目的不是探索“会是什么结果呢”,而是要么符合我期待的结果,我的程序可能没毛病,要么与我期待的结果不同,那么程序肯定哪里错了。

我输入0.718,乘2(再取整的)结果一定是1011才对。

下图中,0.718是我输入的,待求的十进制小数。公式,就是乘2,没有最后结果那么复杂。

我扫了一眼,乘2乘得不错。你可能看出来了,我没有减1,但是当时我并不知道——而这,也没什么影响,我们不必一蹴而就。遇到问题,解决就是了,等遇到问题再说,眼下我还没看出来。

第3步 取整

如下图所示,我给了公式 对同一列上一行 取整。取整的这个函数,是我 bing 搜索到的。关键词当时用的什么不确切地记得了,大致是“excel 取整”。此时如果你不知道 floor, ceiling, round 这些区别,可能这里会纠结一会儿。无妨,即使不知道这些,如果发现问题了,换个公式就是,后面会换的。

这时,我会发现个问题,这也是程序为什么需要 调试 的原因。

这工作马上就完事了,乘2么、取整么,一共就两步,所以就完了。当任务“完成”以后,或者说每次认为完成以后,需要检验是否符合目的。我的目的是把——我跳到标题复制来的——十进制小数转二进制。目标是二进制。但是在结果里出现了2及2以外的数,按说只应该有0和1才对。

第4步 调试-修改

为什么结果里有2,那是因为同一列上一行的那个数字的整数部分就是2。
为什么结果里有5,那是因为同一列上一行的那个数字的整数部分就是5。

所以,取整 没有问题。那么问题出在 乘2里。

我可能需要查一下课本。你可能更厉害,连课本也不用查,就意识到,“乘2”不对望文生义,根据课本中的叙述,乘2这个操作的输入不是上一次的结果,而是上一次的结果取出小数部分。我漏了取出小数部分。

怎么取出小数部分呢?这是比刚才所有讨论更细节,因此也更微小的问题。你可以用完全和我不同的手段,比如求余(求模),转成字符串然后找小数点再分割……无所谓好坏,顺手就行。别忘了,这是个微小的问题。是的,我作为教师可能会PUA你,有更好的方案。然而,为什么要追求更好,什么指标才是更好,就这么十几二十几位数字有性能问题吗?可维护性好不好有那么重要吗,这个技术手段用于一个可抛弃的学习用的工具,而且已经把这个技术手段隔离在这个单元格中了,不会污染其他的部分。最关键的是,这个问题它微小,对全局的技术路线没什么影响。

我把公式改为 =IF(C2>1,C2-1,C2)*2

我还查了一下excel中的if这个函数的参数。第一个参数是逻辑判断的条件,如果为真那么返回第2个参数,如果为假那么返回第3个参数。

复制这个公式,粘贴到 乘2 这一行的其余单元格。好像又很对的样子,根据下一行 取整 的结果。

看起来对了。

你可能不放心,取整 那行公式对不对啊。不知道,而且和我的最终版本不一样。如果增加信心呢,多测几组数据。如果这些数据有代表性,那就更好了。如果有代表性,是个巨大的问题,此处无法展开。也可以“尽力而为”地测几组数据,出了问题——再说。

我测了 0.14,0.718,与交叉检验的结果都一致。

又测了0.01234,结果太糟糕了,全0。我不知道转换的结果是什么,不过肯定不是全0。

为什么呢?噢,因为精度不够。

复制最后一侧,向右粘贴。

很像对的样子,不是全0了。

交叉检验,果然很对。

你可能发现了,第一行后面的数字是错的,我复制并粘贴了“4”。后来我改了,在此不再截图。

4. 补遗

验算,不是标题“十进制小数转二进制”的一部分,因此它的公式怎么一步步改出来的,略去。

我还顺手做了个十进制整数转二进制。

二进制从右往左读。

公式1 除2

公式2 除余

公式3 费了不少步骤,只是为了练习、学习或者手痒,Excel内置了整数十进制转换为二进制的函数。

此文也发布在以下站点。
----
知乎 https://www.zhihu.com/people/yang-gui-fu-52
独立博客 https://younggift.net/
微信公众号 杨贵福
----
以下是我曾经发布博客的站点,有些旧文。
----
豆瓣 - 因为审核"我的日记",不再更新。
https://www.douban.com/people/younggift/
CSDN – 因为要求我登记手机号码的原因是“为了您的安全”,不再更新。
https://blog.csdn.net/younggift?type=blog
blogsopt – 因为从我的机器不可达,无法更新

伊通河的红嘴鸥

有一天坐校车路过伊通河,看河面上一片白点。再看,像水鸟,还有的扇动翅膀正横过空中。赶紧掏出手机拍了几张,放大看,果然是白色大鸟,翅膀张开的样子像海鸥之类的。

仓促之间拍照,没有一张清晰的,放大也很模糊,还有车窗的反光。

发到朋友圈。不一日,同事LDZ老师在群里喊我,之前我发的伊通河水鸟,可能是红嘴鸥,附了一张照片参考。

后来查到,央广网也报道了,https://jl.cnr.cn/ztgz/20241030/t20241030_526957965.shtml。提到2015年开始治理,2019年有红嘴鸥等大量野鸟栖息。印象里,隐约记得这几年见过估计是红头鸭的,不多。

以前只知道候鸟南迁要途经吉林市,因为有大湖大河。偶尔还有报道迷路到了集安、长春的。

又不多久,前辈YK老师问我,是不是去滇池越冬的红嘴鸥,附了一个链接。链接的页面里有不少清晰照片,大鸟在空中特别近距离掠过。滇池水体巨大,望不到对岸,大海一样。空中满眼都是远远近近的白鸟,蔚为壮观。

看到一段文字“在湖岸安家筑巢”,突然我就不审美不浪漫了。哪不对呢?据我所知,鸟类只有在繁殖期才会筑巢。巢是为幼雏特别提供的场所,在越冬地的是能长途跋涉的成鸟,按说不该有巢才对。

那么,需要讨论以下几个问题。1.红嘴鸥的繁殖地是哪里,会不会是滇池。2.红嘴鸥的非繁殖期会不会也筑巢。3.伊通河的红嘴鸥与滇池的是同一品种、同一批吗?顺便,它们的迁徙路线和时间是什么样的?

物种库 http://museum.ioz.ac.cn/species_detail.aspx?id=19266 没有提到这些问题。不过有别的信息。长40厘米左右,翼展1米左右,真大啊。拉丁名,回头用于去维基百科。提到第一冬鸟,后面没提。可能成熟需要不止一年。

对滇池当地和红嘴鸥的报道,还是央广网,https://china.cnr.cn/gdgg/20231119/t20231119_526491686.shtml 提到 “从2~4岁时,红嘴鸥就开始繁殖”。所以第一冬鸟时还是毛头小子小丫头。这些与主题无关,只是有趣。提到了时间和地点,“红嘴鸥每年11月下旬到次年3月下旬在昆明越冬,4月初时又飞到蒙古国西部、俄罗斯贝加尔湖地区和北极圈内等地繁殖后代。”在北方繁殖。还提到“红嘴鸥的数量从1984年的2000只,阶段性跳跃式地增长至2021年的44000只。其中,少部分红嘴鸥不再离开滇池水域进行迁徙,但也未见在滇池筑巢繁殖后代”。有的成为了留鸟,不再迁徙,但未见筑巢繁殖。提到当地政府投入力量环保。还认为未筑巢可能因为人类溺爱,似乎暗示日子过得好就不需要鸟巢了,我怀疑想多了,可能仅因为不在当地繁殖。

这里有张分布图,https://baike.baidu.com/item/%E7%BA%A2%E5%98%B4%E9%B8%A5/698557

为清晰起见,我复制过来。

可以看到,标注(原产地)的,包括东北,粗略看起来长春也在边缘。在滇池,差不多是身为旅鸟或者视作非繁殖地越冬。不仅如此,凡太平洋海岸线附近,整个中国、朝鲜、日本、东南亚,都是非繁殖地。南南亚岛屿和大洋洲的北部岛屿也有存在。所以,不难断言长春伊通河的红嘴鸥是不是就是滇池的,甚至不能断言滇池就是迁徙的最南端,也可能只是经停。

跨大西洋两岸,加拿大、格陵兰鸟、欧洲、红海、阿拉伯海沿岸、印度西岸、青藏高原以南也有分布。不过那些和滇池的,看起来不是同一批。

云南对当地的红嘴鸥做了标记,观测离开昆明以后的迁徙路线。https://www.sohu.com/a/42676719_115092 提到发现了3条路线。从这里看没有经过东北的。其中若尔盖湿地似乎就是红军长征所过草地。

http://km.bendibao.com/tour/20221012/66018.shtm 则提到“ 迁徙新路线  发现了一条往东北方向去的一条红嘴鸥的迁徙路线,从昆明出发到了黄河,然后到东北停歇,然后继续往东北方向,到达了俄罗斯,有4000多公里的直线距离,飞行比较长的一只红嘴鸥,它一共飞行了8000公里。”这一段话中提到三次“东北”,其中两次为“东北方向”,指的当是角度,另一次是“到东北停歇”指的当是“东北三省”。提到有条路线过滇池后翻越喜马拉雅山去了缅甸。

https://baijiahao.baidu.com/s?id=1783138058708100450,提到筑巢时间。“每年的4到6月是红嘴鸥的繁殖期,红嘴鸥通常在地面上筑巢”。按前文对迁徙时间和地点的资料,那么此时在北方,不在滇池。虽然在北方筑巢并不能断定在滇池就不筑巢,但是如果红嘴鸥如果和一般鸟类相同,只在繁殖期筑巢的话,那么4~6月繁殖结合迁徙时间和地点可以得出结论在滇池不筑巢。同一文章,也提到了在昆明即滇池筑巢,“昆明周边的湿地和湖岸地也为红嘴鸥提供了理想的生活居所。这些地方有大片的芦苇荡和湖中岛屿,为红嘴鸥提供了安全的筑巢环境”。

用拉丁文名在维基百科 wikipedia 查,重定向至 Black-headed_gull 黑头鸥,这是红嘴鸥的别我。有一段文字,“It breeds in colonies in large reed beds or marshes, or on islands in lakes, nesting on the ground. Like most gulls, it is highly gregarious in winter, both when feeding or in evening roosts.”在陆地筑巢。在冬天成群活动,进食或夜晚……此处用了个词 栖息。这可以作为旁证,红嘴鸥在夜晚栖息时,并不需要巢。

综上,在滇池“筑巢”的说法,我怀疑是比喻义。一般鸟类只在繁殖时才筑巢,没有找到红嘴鸥例外的说法。红嘴鸥在北方繁殖,在南方途径或越冬。所以,在滇池应该不筑巢。

红嘴鸥向南迁徙的范围非常大,整个中国的东部沿海、东南亚、大洋洲都可能是目的地。包括滇池。滇池可能部分红嘴鸥的途经地,也可能是部分红嘴鸥的目的地。长春伊通河的红嘴鸥,可能与滇池的是同一只,也可能不是同一批。

读到这里,你会不会有点遗憾?可能会想,原来红嘴鸥的故乡、娘家不是滇池啊,原来有的还会跑到国外(无论向南还是向北,无论繁殖地还是越冬地)去啊,原来欧洲也有不是特有的啊,原来……

红嘴鸥的出现,至多能一定程度上得出结论,生态环境好转。因为“我们盖上了大工厂”十有八九不会引得“燕子为啥来”。还能得出结论,市民友好有利于红嘴鸥出现。滇池距离昆明市区只有5公里,所以市民非常容易到达。如果不够友好,杀死或猎捕或虐待都会使得红嘴鸥跑远,毕竟这家伙每天可以飞150公里。滇池距离市区近,可能也是大家会关注,有那么多照片的原因。滇池距离市区,我也没有看到就相信了,而是查证了一下,用百度地图量了两个距离,作为与网上信息的交叉验证。

对红嘴鸥的进一步拟人化,在哪里筑巢、安家、当作娘家,所谓引喻失义,再发展就是数地争当红嘴鸥故乡,并作为证据表明哪里是最好的地方,近而表明我热爱这片土地,我才是真正的东北人。

再发展,就是云南的朋友骂我,“杨老师你看你这不好吧”。万一滇军来问罪,我会把最近读到的一段文字发给他。

雷海宗在《中国文化与中国的兵》说了下面一段。

----引文开始---中间有省略----

北京猿人发现之后,有些夸大习性未除的国人更欢喜欲狂,认为科学已证明中国

历史可向上拉长几十万年。殊不知这种盗谱高攀的举动极为可笑,因为北京猿人

早已断子绝孙,我们绝不会是他们的后代。由史学的立场来看,北京人的发现与

一个古龙蛋的发现处在同等的地位,与史学同样的毫不相干。据今日所知,旧石

器时代

但不见得某一地的新石器时代人类就是同地后来开化人类的祖先,某一地的新石

器文化也不见得一定与同地后来的高等文化有连带的关系。因为我们日常习用

“中国史”“英国史”“欧洲史”一类的名词,无意之间就发生误会,以为一块

地方就当然有它的历史。

由自然科学的立场来看,地方也有历史,但那是属于地质学与自然地理学的范围

的,与史学本身无关。地方与民族打成一片,在一定的时间范围以内,才有历史。

民族已变,文化的线索已断,虽是同一地方,也不是同一的历史。这个道理应当

很明显,但连史学专家也时常把它忽略,无论在中国或西洋,“上古史”的一切

不可通的赘疣都由这种忽略而发生。所以关于任何地方的上古史或所谓“史前

史”,即或民族文化都一贯相传,最早也只能由新石器时代说起,此前的事实无

论如何有趣,也不属于史学的范围。

----引文结束---

以上对于事实的讨论万一错了,你刚好知道,万望告诉我,我好纠正。多谢!

此文也发布在以下站点。

----

知乎 https://www.zhihu.com/people/yang-gui-fu-52

独立博客 https://younggift.net/

微信公众号 杨贵福

----

以下是我曾经发布博客的站点,有些旧文。

----

豆瓣 - 因为审核"我的日记",不再更新。

https://www.douban.com/people/younggift/?_i=0098558fqLUL9h

CSDN – 因为要求我登记手机号码的原因是“为了您的安全”,不再更新。

https://blog.csdn.net/younggift?type=blog

blogsopt – 因为从我的机器不可达,无法更新