以Javascript 53位数字格式

时间:2018-04-27 11:46:51

标签: javascript numbers timestamp precision

背景

我正在从具有以8字节(64位)编码的时间戳的缓冲区解码数据。

通常这不会有问题,除了JavaScript中的Number仅适用于最多53位的数字 - 然后它会失去精度。

问题

这意味着如果我将该时间戳存储在JavaScript编号中,我将失去精度,因为Number格式不足以存储时间戳。

由于这是一个需要时间精度至少直到秒的应用程序,我并不热衷于丢失太多精度。

实施例

为了证明我的观点,这里是一个16位长的时间戳的十六进制字符串。如果您使用的是Node.js,可以像下面这样进行测试:

//a small timestamp from our current time in history
var buf = Buffer.from(
    "162F1544EA81242A",
    "hex"
);

buf.readUInt( 0, 6 ); // lost 2 bytes of precision here!

这个时间戳应该会在未来给出一些价值:

  

假设此时间戳以微秒(1 / 1,000,000秒)为单位:   格林尼治标准时间:2020年8月27日星期四上午9:16:18.476 AM您所在的时区:   2020年8月27日星期四上午11:16:18.476 AM GMT + 02:00 DST

问题

  • 如果以JavaScript 53位数字格式保存,64位时间戳会松散多少精度(以毫秒为单位)?

2 个答案:

答案 0 :(得分:1)

JavaScript的Number.MAX_SAFE_INTEGER,2 ^ 53 - 1,其值为9,007,199,254,740,991。但是,要意识到除了53位整数精度之外还有一个符号位,所以如果你的时间戳是有符号的,你也可以利用它。

让我们坚持认为这是一个以微秒为单位的时间戳,而不是毫秒。 53位加上符号位覆盖了多少时间范围?将9,007,199,254,740,991微秒转换为年,大约为±285年。对于大多数应该足够好的目的。

如果您选择降低某些分辨率并转换为毫秒,那么您的时间戳可以涵盖±285,000年的范围。

答案 1 :(得分:0)

这显然很容易测试,JavaScript使用正好64位浮点来存储数字,浮点意味着精度会随着数字的增加而减少,所以选择你需要的最大可能值并尝试减去1,2,3等。直到你得到一个不同的值,这样你就可以准确地记录最小的时差。