📜  在线转换有符号的 64.64 位定点数 - Javascript (1)

📅  最后修改于: 2023-12-03 15:37:45.851000             🧑  作者: Mango

在线转换有符号的 64.64 位定点数 - Javascript

简介

在很多嵌入式系统和通讯协议中,经常使用定点数表示浮点数,比如 16.16 位定点数和 32.32 位定点数。64.64 位定点数可以表示更高的精度,但在计算机中无法直接转换为浮点数,需要特别的算法。

本文介绍使用 Javascript 实现在线转换有符号的 64.64 位定点数的算法,并提供代码示例。

定点数表示方法

定点数是以固定小数点位置表示的数字,它的值是整数部分和小数部分的和,具体表示方法如下:

给定一个整数 n,将该整数左移位长为 p,即可得到定点数 n × 2^p。

例如,16.16 位定点数表示方法是将数值乘以 2^16,然后将结果表示成二进制数。例如,十进制数 1.234 的 16.16 位定点数表示为二进制数 00000001000011100100001100000000。

64.64 位定点数的表示方法类似,即将数值乘以 2^64。然后将结果表示成二进制数。

转换算法

对于 64.64 位定点数,可以将其分为高 64 位和低 64 位,其中高 64 位表示整数部分,低 64 位表示小数部分。

设要转换的定点数为 a,高 64 位为 a_high,低 64 位为 a_low。

首先,应该将 a 转为二进制数,然后分别取出高 64 位和低 64 位。由于 Javascript 的数值类型不能表示超过 2^53 的整数,因此可以使用 BigInteger 库。

代码示例如下:

// 引入 BigInteger.js 库
const { BigInteger } = require('jsbn');

// a 为要转换的定点数
const a = "1234567890123.4567890123456";

// 将 a 转为 BigInteger 类型
const a_bigint = new BigInteger(a.replace(".", ""), 10);

// 获取 a 的二进制表示,并分别取出高 64 位和低 64 位
const binary_str = a_bigint.toString(2);
const binary_len = binary_str.length;
const a_high = binary_str.slice(0, binary_len - 64);
const a_low = binary_str.slice(binary_len - 64);

转换完成后,就可以将 a_high 和 a_low 转回十进制数,进而得到原始的定点数。具体代码示例如下:

// 将高 64 位和低 64 位转回二进制数,并组合成一个 128 位的二进制数
const binary_str = a_high + a_low;
const a_binary = new BigInteger(binary_str, 2);

// 将二进制数除以 2^64,得到原始的定点数
const a_value = a_binary.divide(new BigInteger("18446744073709551616")).toString();

// 将整数部分和小数部分分离出来
const a_int = a_value.slice(0, a_value.length - 16);
const a_dec = a_value.slice(a_value.length - 16).padStart(16, "0");

// 将整数部分和小数部分组合成一个带小数点的字符串
const a_str = a_int + "." + a_dec;
完整代码示例
// 引入 BigInteger.js 库
const { BigInteger } = require('jsbn');

function convert_fixed_point_number(a) {
  // 将 a 转为 BigInteger 类型
  const a_bigint = new BigInteger(a.replace(".", ""), 10);

  // 获取 a 的二进制表示,并分别取出高 64 位和低 64 位
  const binary_str = a_bigint.toString(2);
  const binary_len = binary_str.length;
  const a_high = binary_str.slice(0, binary_len - 64);
  const a_low = binary_str.slice(binary_len - 64);

  // 将高 64 位和低 64 位转回二进制数,并组合成一个 128 位的二进制数
  const binary_str2 = a_high + a_low;
  const a_binary = new BigInteger(binary_str2, 2);

  // 将二进制数除以 2^64,得到原始的定点数
  const a_value = a_binary.divide(new BigInteger("18446744073709551616")).toString();

  // 将整数部分和小数部分分离出来
  const a_int = a_value.slice(0, a_value.length - 16);
  const a_dec = a_value.slice(a_value.length - 16).padStart(16, "0");

  // 将整数部分和小数部分组合成一个带小数点的字符串
  const a_str = a_int + "." + a_dec;

  return a_str;
}
总结

在线转换有符号的 64.64 位定点数可以使用 Javascript 中的 BigInteger.js 库实现。通过将定点数转为二进制数,并分别取出高 64 位和低 64 位,然后将其转回十进制数即可实现转换。

完整代码示例如上。