由数据存储想到的
突然看到自己写的一段代码,于是想到了当初纠结的经历。正巧和一些东西联系起来。
数据越界问题
- 对于计算机的数字系统来说,不像用手写的一样,想写多少就写多少,它是存在一个限制条件的。
对于一个无符号型16位的数来说,它能表达的最小数字为0即2^0 - 1,最大数字为2^16 - 1.同理32位,64位等。
在运算符中存在+=
,-=
这样的操作。
以下便是我在设计中的一个代码,大体框架:
uint16a += uint16b - uint16c;
后来,鬼使神差的考虑考虑到了数据的越界问题。
- 假如uint16b < uint16c怎么办?后面的数字不是越界了吗?
- 假如uint16b - uint16c 的结果和uint16a相加,越界了怎么办?
后来,莫名奇妙的改成了:
uint16a += uint16b;
uint16a -= uint16c;
大概那个时候,我所考虑的是为了引起不必要的歧义,才将上面的那个语句拆封为两个简单语句的。毕竟 a += b - c
会有一定的歧义。
后来,针对这个问题的值上,觉得这种无法避免。以下是我借鉴的模型。
计算机的数字系统,可以看做一个循环。即最大 + 1 = 最小
,最小 - 1 = 最大
,类比与和我们密切相关的钟表。
时钟的指针所指向的位置表示数字,一天的最晚点与一天的最早点相连接。那么,无论我们怎么去做运算:
1.相当与去做指针的顺时针转动与逆时针转动。
2.我们可以算好要转动的角度与方向,一次性到位。
其结果和一步一步执行的结果一样,同理可用于其他循环类结构。
隔了这么长时间,突然想到了一个很蠢的问题,可能那个时候没有意识到这些,做了一些蠢事。
以下展开,大致的意思和这个意思一样。
有一次,用系统时钟来记录时间,以下是代码:
uint32 TimeDelay()
{
uint32 TimeNow;
uint32 TimeLast;
if(TimeNow > TimeLast)
return TimeNow - TimeLast;
else
return 0xffff - TimeLast + TimeNow;
}
实现起来比这复杂,大致意思为这样。现在想想,还是太年轻了。直接一个return TimeNow - TimeLast
就够了,压根就不用判断。
细想起来,确实是有点意思。