using namespace HsingYun

The only thing we have to fear is fear itself

0%

想必大家一定或多或少听过一个历史悠久的快速计算平方根倒数的算法,这个算法由于出现在《雷神之锤III竞技场》源代码中而被人们所熟知,每次看到这个算法,内心除了惊呼NB外,对其背后的原理一脸懵逼,加上最近正好在学习IEEE754标准,于是就索性利用周末寻找资料,看看远古时期的那些大神们是如何利用自己的智慧挑战硬件的极限,也看看后面的大神们是如何探究和揭秘这个算法的。

阅读全文 »

1 简介

AMD64 架构是 x86 架构的一种扩展。任何实现 AMD64 架构规范的处理器都会为早期的 Intel 8086 架构(包括 Intel 386,Intel Pentium 和 AMD K6-2 这类 32 位处理器)提供兼容模式。满足 AMD64 ABI 的操作系统可以为这些兼容模式下运行的程序提供支持。AMD64 ABI 并不适用于这类程序。本文档仅适用于在 AMD64 架构提供的 “长”模式下运行的程序。

使用 AMD64 指令集的二进制可以被编写为 32 位模型的程序,在这种模型下,其 C 语言数据类型 int、long 和所有的指针类型是 32 位对象(ILP32);也可以被编写为 64 位模型的程序,其 C 语言数据类型 int 是 32 位对象,但是 long 和 所有的指针类型是 64 位对象(LP64)。该规范涵盖了 LP64 和 ILP32 编程模型。

除非另有说明,AMD64 架构的 ABI 遵循 Intel386 ABI 中描述的约定。AMD64 ABI 仅指示对 Intel386 ABI 进行改进的地方,而不是复制全部的 Intel386 ABI。

鉴于没有尝试为 C 语言之外的语言特殊指定 ABI,这里假设很多编程语言可以直接链接用 C 语言编写的代码,本文档的 ABI 规范也遵守这个假设。

阅读全文 »

更多参见:

基本规定

  • 两种基本的浮点格式:单精度、和双精度

    IEEE 单精度格式具有 24 位有效数字精度,并总共占用 32 位。 IEEE 双精度格式具有 53 位有效数字精度,并总共占用 64 位

  • 两种扩展浮点格式:单精度扩展双精度扩展

    此标准并未规定这些格式的精确精度和大小,但它指定了最小精度和大小。例如,IEEE 双精度扩展格式必须至少具有 64 位有效数字精度,并至少总共占用 79 位

  • 浮点运算的精确度要求:平方根余数将浮点格式的数舍入为整数值在不同浮点格式之间转换在浮点和整数格式之间转换以及比较

    求余和比较运算必须精确无误

    其他的每种运算必须向其目标提供精确的结果,除非没有此类结果,或者该结果不满足目标格式。对于后一种情况,运算必须按照下面介绍的规定舍入模式的规则对精确结果进行最低限度的修改,并将经过此类修改的结果提供给运算的目标

  • 在十进制字符串和两种基本浮点格式之一的二进制浮点数之间进行转换的准确性、单一性和一致性要求

    对于在指定范围内的操作数,这些转换必须生成精确的结果(如果可能的话),或者按照规定舍入模式的规则,对此类精确结果进行最低限度的修改。对于不在指定范围内的操作数,这些转换生成的结果与精确结果之间的差值不得超过取决于舍入模式的指定误差

  • 五种类型的 IEEE 浮点异常,以及用于向用户指示发生这些类型的异常的条件

    无效运算

    除以零

    溢出

    下溢

    不精确

  • 四种舍入方向

    向最接近的可表示的值,当有两个最接近的可表示的值时首选“偶数”值

    向负无穷大舍入(向下)

    向正无穷大舍入(向上)

    向 0 舍入(截断)

  • 舍入精度

    如果系统提供双精度扩展格式的结果,则用户可以指定将此类结果舍入到单精度格式或双精度格式的精度

阅读全文 »

随手使用 github action 自动化部署,懒得手动去执行 npx hexo deploy --generate

仓库结构

1
2
3
4
5
6
7
$ tree hexo      > origin/hexo
hexo
├── _config.yml
├── package.json
├── README.md
├── scaffolds
└── source > origin/post (branch as submodule)
阅读全文 »

最近沉迷于造轮子不可自拔,在实现一个底层网络库时,发现了一个奇怪的 bug:自己写的 server 在 localhost 下一切正常,一旦部署到自己的 VPS 上,所以的请求都无法被 accept

通过 TCPDump 查看握手情况,发现一个诡异的问题,服务器可以收到 SYN,同时当前状态也可以切换为 SYN-RCVD,然后整个连接到此为止,客户端无论如何都收不到服务端回复的 ACK,导致客户端不停的发送 SYN

排查网络路由情况无果后,只能怀疑是代码写错了,开始了愚蠢的二分定位 bug。终于发现了诡异的两行代码:

1
2
int level = family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
auto ret = ::setsockopt(fd, level, SO_REUSEADDR, &reuse_addr, sizeof(reuse_addr));

注释掉以后,发现一切正常了起来。仔细观察代码,发现我当时脑子一热,将 setsockopt 写在了 IP 协议级别了,重新改回 SOL_SOCKET 后问题解决。

1
auto ret = ::setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse_addr, sizeof(reuse_addr));
阅读全文 »

你好(Hello)世界(world) ()(hǎo)(shì)(jiè)
hello,worldcpp
1
2
3
4
5
6
#include <iostream>

int main() {
std::cout << "Hello, world!" << std::endl;
return 0;
}
阅读全文 »