JIGZEG.INFO

1. VS Code pet

发布于18时47分

一二三四五六日
一2345678910111213141516171819202122232425262728293031
一二三四五六日
二2345678910111213141516171819202122232425262728
一二三四五六日
三2345678910111213141516171819202122232425262728293031
一二三四五六日
四23456789101112131415161718192021222324252627282930
一二三四五六日
五2345678910111213141516171819202122232425262728293031
一二三四五六日
六23456789101112131415161718192021222324252627282930
一二三四五六日
七2345678910111213141516171819202122232425262728293031
一二三四五六日
八2345678910111213141516171819202122232425262728293031
一二三四五六日
九23456789101112131415161718192021222324252627282930
一二三四五六日
十2345678910111213141516171819202122232425262728293031
一二三四五六日
土23456789101112131415161718192021222324252627282930
一二三四五六日
丰2345678910111213141516171819202122232425262728293031
2026
02.05
02.05
02.05
02.05
02.05

年度统计

一●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●二●●●❶●●●●●●●●●●●●●●●●●●●●●●●三●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●四●●●●●●●●●●●●●●●●●●●●●●●●●●●●●五●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●六●●●●●●●●●●●●●●●●●●●●●●●●●●●●●七●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●八●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●九●●●●●●●●●●●●●●●●●●●●●●●●●●●●●十●❶●●●●●●●●●●●●●●●●●●●●●●●●●●●●土●●●●●●●●●●●●●●●●●●●●●●●●●●●●●丰●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

目前为止,此博客已经发布了 16 篇文章,共计 1.43w 字。

VS Code pet

发布


召唤方式

在 Chat 对话框中输入 /vscode-pet,然后 “回车键” 确认,召唤!

交互内容

详见:VS Code: VS Code Pet的官方介绍。

内容主要是鼠标/键盘事件交互,还有就是达成一些关键操作点后,触发“成就”,解锁“宠物的帽子装饰”。

宠物在“睡眠”状态下,会展示 “打呼噜” 动画,鼠标点击或者在Chat输入框内键入文字来唤醒。

在一般状态下,会在特殊情境展示不同的交互动画,例如光标眼动跟随、鼓掌、爱心动画等。通过鼠标向上轻扫抛起宠物开始进行交互小游戏:在宠物落在输入框(地面)前接住,会记1积分;落在输入框上或者掉在输入框外,则游戏结束。

宠物被聚焦时,按下“左/右”方向键,可以控制移动。

VS Code Pet目前内置了13个可见“成就”,每个成就达成后,可以解锁一个对应的装饰帽子——可以通过在命令面板运行 Developer: Unlock All Pet Achievements 命令,直接解锁所有“成就帽子”来跳过。

预览


此文被收纳在#写写代码#类目下,被贴上了#游戏#标签

有趣的“码神挑战”

发布


昨天在B站刷到一位叫“鱼皮”的Up的视频,内容是介绍面向广大程序员发起的“码神挑战”答题活动。想要证明自己的“编程实力”的同学可以去看看,答题的同时巩固一下自己的编程知识,同时收获一份快乐~ 😆

点击此处开始挑战。

P.S.

已通关,学无止境!(全程开发者控制台工具没关过~有几关没解出来,切到移动端视图跳过去的)


此文被收纳在#写写代码#类目下,被贴上了#1024程序员节#标签

给Life平台加上动账消息推送提醒

发布


公司有一个Life平台,登录之后可以查看饭卡的余额和消费记录等数据。但体验下来,觉得这个平台有诸多需要改进的地方:一是Life平台后端的Token有效期非常短,没多久就失效要重新登录;二是前端没有适配移动端,操作不便;三是金额消费和充值没有动账提醒,无法实时查看消费情况。

为了解决上述诸多不便,花时间用Python实现了一个数据实时爬取、更新、统计、动账推送的脚本。利用Cron定时任务,在一般时段设置频率为半小时执行一次数据同步任务,在饭点高峰时段每分钟执行,一旦监测到有新的动账记录,会通过PushBullet将动账相关信息发送到手机上。

目前服务端部署在了一台Root了的随身Wi-Fi上的Linux Deploy里,刚好可以把每个月用不完的流量分担出去一点。

同时,也为随身Wi-Fi的后台写了一个插件,可以手动刷新查看当前的账户资金情况和最近的一条交易记录。

目前唯一的不足:受限于国内厂商系统推送政策,PushBullet需要一直挂在后台运行,才可以收到推送消息;而且,尽管已经设置了PushBullet省电策略为“无限制”了,但切到后台后,仍然有概率会延迟几分钟才可以收到推送通知,打开App后是可以立即接收到的,未来可能需要看看有什么省事的通知替代方案。


此文被收纳在#写写代码#类目下,被贴上了#Python#标签

终究还是迟来

发布


9小时体验评价:质量还是一如既往高,无论是美工场景虫物设计还是音乐音效,亦或是手柄的振动反馈。唯一的槽点,游戏翻译仍有待加强。


此文被收纳在#星碎札#类目下,被贴上了#游戏#标签

关于IEEE 754浮点数标准

发布


IEEE 754(IEEE Standard for Floating-Point Arithmetic,即IEEE二进制浮点数算数标准),定义了表示浮点数的格式(包括-0)与反常值(denormal number),无穷Infinity与非数值(NaN,Not a Number)等数值表示规则和方法 [1]。

二进制浮点数表示法

JS使用IEEE 754双精度64位二进制格式来表示数值类型 [2]。在IEEE 754标准中,一个双精度64位数字包含以下几个部分(从左往右):

  • sign(符号位,占用1bit),表示这个数是正/负数,0表示正数;1表示负数
  • exponent(指数位,占用11bit),表示将这个浮点数以科学计数法形式展示的指数
  • mantissa(有效数字位,占用52bit),表示这个浮点数以科学计数法形式展示的底数

二进制、十进制互相转换

回顾一下,二进制和十进制互相转换的方法:

二进制转十进制:例如一个二进制整数:01101101,转换为十进制的运算过程如下:

0×27+1×26+1×25+0×24+1×23+1×22+0×21+1×20=1090 \times 2^7 + 1 \times 2^6 + 1 \times 2^5 + 0 \times 2^4 + 1 \times 2^3 + 1 \times 2^2 + 0 \times 2^1 + 1 \times 2^0 = 109

得到 (1101101)2=(109)10(1101101)_2 = (109)_{10}。

十进制转二进制:例如十进制数109,转换为二进制的运算过程如下:

109÷2=54余 154÷2=27余 027÷2=13余 113÷2=6余 16÷2=3余 03÷2=1余 11÷2=0余 1 \begin{align*} 109 \div 2 &= 54 \quad &\text{余 } 1 \\ 54 \div 2 &= 27 \quad &\text{余 } 0 \\ 27 \div 2 &= 13 \quad &\text{余 } 1 \\ 13 \div 2 &= 6 \quad &\text{余 } 1 \\ 6 \div 2 &= 3 \quad &\text{余 } 0 \\ 3 \div 2 &= 1 \quad &\text{余 } 1 \\ 1 \div 2 &= 0 \quad &\text{余 } 1 \end{align*}

得到 (109)10=(1101101)2(109)_{10} = (1101101)_2。

十进制转二进制:对于小数例如0.8125,使用“乘2取整法”:

0.8125×2=1.625⇒取整 10.625×2=1.25⇒取整 10.25×2=0.5⇒取整 00.5×2=1.0⇒取整 1\begin{align*} 0.8125 \times 2 &= 1.625 &\Rightarrow&\quad \text{取整 } 1 \\ 0.625 \times 2 &= 1.25 &\Rightarrow&\quad \text{取整 } 1 \\ 0.25 \times 2 &= 0.5 &\Rightarrow&\quad \text{取整 } 0 \\ 0.5 \times 2 &= 1.0 &\Rightarrow&\quad \text{取整 } 1 \\ \end{align*}

得到 (0.8125)10=(0.1101)2(0.8125)_{10} = (0.1101)_2

二进制转十进制:对于二进制小数如0.1101:

1×2−1+1×2−2+0×2−3+1×2−4=0.8125 1 \times 2^{-1} + 1 \times 2^{-2} + 0 \times 2^{-3} + 1 \times 2^{-4} = 0.8125

得到 (0.1101)2=(0.8125)10(0.1101)_2 = (0.8125)_{10}

双精度64位浮点数表示

如果使用IEEE 754标准来表示双精度浮点数数值0.1,可按照如下步骤来手动计算推导:

首先,可以比较简单地知道符号位(Sign)的位的值为0;

S =0S_\ = 0

接下来,利用“乘2取整法”,将0.1转换为二进制:

0.1×2=0.2⇒取整 00.2×2=0.4⇒取整 00.4×2=0.8⇒取整 00.8×2=1.6⇒取整 10.6×2=1.2⇒取整 10.2×2=0.4⇒取整 00.4×2=0.8⇒取整 00.8×2=1.6⇒取整 10.6×2=1.2⇒取整 1 .......\begin{align*} 0.1 \times 2 &= 0.2 &\Rightarrow&\quad \text{取整 } 0 \\ \\ 0.2 \times 2 &= 0.4 &\Rightarrow&\quad \text{取整 } 0 \\ 0.4 \times 2 &= 0.8 &\Rightarrow&\quad \text{取整 } 0 \\ 0.8 \times 2 &= 1.6 &\Rightarrow&\quad \text{取整 } 1 \\ 0.6 \times 2 &= 1.2 &\Rightarrow&\quad \text{取整 } 1 \\ \\ 0.2 \times 2 &= 0.4 &\Rightarrow&\quad \text{取整 } 0 \\ 0.4 \times 2 &= 0.8 &\Rightarrow&\quad \text{取整 } 0 \\ 0.8 \times 2 &= 1.6 &\Rightarrow&\quad \text{取整 } 1 \\ 0.6 \times 2 &= 1.2 &\Rightarrow&\quad \text{取整 } 1 \\ & \ ... &....& \end{align*}

得到 (0.1)10=(0.00011‾)2(0.1)_{10} = (0.0\overline{0011})_2,是一个无限循环小数,循环节为 0011。

然后使用科学计数法,将这串二进制小数写成科学计数法形式:

(0.000110011...)2=(1.110011001...)2×2−4(0.000110011...)_2 = (1.110011001...)_2 \times 2^{-4}

可以知道,指数位为-4,因为指数部分(Exponent)采用“偏移编码”(目的是为了在二进制中能同时表达正指数和负指数,并且避免使用额外的符号位,还可以保留特殊值),所以实际的指数 E =−4+1023E_\ = -4 + 1023(为什么是+1023?因为指数位占用11bit,211=20482^{11} = 2048,中点是1023)。

故:

E =−4+1023E_\ = -4 + 1023

1019转换为11位的二进制:

(1019)10=(01111111011)2(1019)_{10} = (01111111011)_2

接下来是有效数字位(mantissa),即二进制科学计数法的底数 (1.110011001...)2(1.110011001...)_2,取出小数点后52位(为什么只取小数点后的值?因为在科学计数法下,只保留小数点前1位,而在二进制形式下小数点前的那一位永远会是1,所以可以直接直接忽略)。

所以:

M =1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001M_ \ = 1001\ 1001\ 1001\ 1001\ 1001\ 1001\ 1001\ 1001\ 1001\ 1001\ 1001\ 1001\ 1001

最终,我们得到0.1的双精度64位浮点数每位的值:

S E M
0 01111111011 1001100110011001100110011001100110011001100110011001

封装函数doubleToBinaryString和binaryStringToDouble

/**
 * 数字转 IEEE 754 双精度二进制字符串
 * @param {Number} num 任意数字
*/
function doubleToBinaryString(num) {
  const buffer = new ArrayBuffer(8); // 64 位 = 8 字节
  const view = new DataView(buffer);

  // 把数字写入 buffer(使用大端模式)
  view.setFloat64(0, num, false); // false 表示使用 big-endian

  let binaryStr = "";
  for (let i = 0; i < 8; i++) {
    const byte = view.getUint8(i);
    binaryStr += byte.toString(2).padStart(8, '0');
  }

  return binaryStr;
}
/**
 * IEEE 754 双精度二进制字符串转数字
 * @param {String} binaryString 任意表示双精度二进制的字符串
*/
function binaryStringToDouble(binaryString) {
  const bstr = binaryString.replaceAll(/[^\d]/g, '') // 仅保留数字
  if (bstr.length !== 64) {
    throw new Error("输入必须是 64 位二进制字符串");
  }

  // 将每 8 位转成字节,填入 Uint8Array
  const bytes = new Uint8Array(8);
  for (let i = 0; i < 8; i++) {
    const byteStr = bstr.slice(i * 8, (i + 1) * 8);
    bytes[i] = parseInt(byteStr, 2);
  }

  // 用 DataView 读取 float64(双精度)数字
  const view = new DataView(bytes.buffer);
  return view.getFloat64(0, false); // false 表示 big-endian(高位在前)
}

浮点数的基础运算原理

此处,以0.1 + 0.2为例,介绍一下双精度数值两者+运算的运算过程:

首先,使用封装好的doubleToBinaryString函数,得到两者的IEEE 754的结构:

Number S E M
0.1 0 011 1111 1011 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1010
0.2 0 011 1111 1100 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1010

然后,对齐指数(E):

0.1的指数位为011 1111 1011,(01111111011)2=(1019)10(011 1111 1011)_2 = (1019)_{10},故,指数为 1019−1023=−41019 - 1023 = -4

继续阅读…


此文被收纳在#计算机原理#类目下,被贴上了#IEEE##二进制#标签
← 早期文第 1 页 / 共 3 页近期文 →