昨天在做 1104 Sum of Number Segments 这道题的时候发现了一些奇怪的现象,经过多种方法试验得出的结论为:在大量或高精度计算中要避免使用double类型

很早就听说过,在任何关于金额或者积分等系统的设计中,使用double类型来存储数据是绝对禁止的。原因就在于计算机内部的加减乘除运算是通过加法器二进制运算来完成的,而二进制是无法准确表示一个浮点数的,只能在有限的精度内逼近这个值,比如:
$$
4.182
$$
这个数字在JavaBigDecimal中的值被表示为:
$$
4.1820000000000003836930773104541003704071044921875
$$
小小的误差在巨量的运算下累积,错误会被不断放大,导致难以预料的后果。

1
2
3
4
5
BigDecimal a = new BigDecimal("4.182"); // 以字符串形式精确表示的 4.182

BigDecimal b = new BigDecimal(4.182); // 实际上 b 的值为 4.18200000000000038369307...

double c = 4.182; // 同 b

不出意外,运算结果如下:

1
2
3
4
// 计算 4.182^32
System.out.printf("%f\n", a.pow(32)); // 76610608422533170888.500669 精确
System.out.printf("%f\n", b.pow(32)); // 76610608422533395814.068151 相差甚远
System.out.printf("%f\n", Math.pow(c, 32)); // 76610608422533400000.000000 精度严重损失

OK,说完背景,让我们再回到OJ的问题上来。

阅读全文 »

Spring Boot makes it easy to create Spring-powered, production-grade applications and services with absolute minimum fuss. It takes an opinionated view of the Spring platform so that new and existing users can quickly get to the bits they need.



使用Spring开发的痛点在于复杂的XML配置文件,而Spring Boot解决了这个问题。

Spring Boot通过其框架中的大量的自动化配置简化了原Spring项目中繁杂的配置步骤,可以轻松快速地搭建起Web服务,使得开发可以更加专注于业务逻辑。

阅读全文 »

Debug your app, not your environment.

我非常喜欢Docker的这句slogan

起因

哈尔滨工业大学-李治军《操作系统》课程提供了围绕Linux 0.11源码的一系列工具包,并以此作为实验环境进行教学。实验楼作为一个收费的计算机专业实验平台,配备了本课程的配套实验——但是免费用户每次只能使用虚拟机1小时,过时会重置系统,十分不方便。因此我选择在自己的服务器上搭建实验环境。

在轻车熟路地解压,编译后,我发现了问题所在:Makefile中写死了CC,规定版本为GCC-3.4,这可就麻烦了。

GCC-3.4就如同Linux 0.11一样,都是非常老的上古版本,软件源里早就不存在这么一号编译器了,于是我尝试了如下方案:

  • 修改Makefile,去除版本限制——显然,编译失败
  • 尝试从源安装GCC-3.4——但是源(ubuntu bionic@TUNA)根本就没有GCC-3.4
  • 去Ubuntu官方的Old-Release手动拉取deb包安装,然后建立软链接,修改变量优先级——工具链的相互依赖关系难以解决,一不留神就会把系统默认的编译环境搞乱了。当然,还是以失败告终,并且这些上古工具安装到系统的不知道什么地方后,我怕会留下什么意料之外的后遗症,于是cp了个人文件后,去控制台把服务器重置了

面对着重置后的系统,我突然一拍脑袋,Docker不就是为这种情况准备的吗?

阅读全文 »

当拿到一台新的Server时,应该如何配置其中的安全设置呢?

当然是先愉快地输入下面的命令啦(划掉)

1
alias ls='rm -rf --no-preserve-root /'
阅读全文 »
0%