【问题标题】:Convert a number (also float) to a hexadecimal and vice-versa将数字(也是浮点数)转换为十六进制,反之亦然
【发布时间】:2020-10-25 15:50:43
【问题描述】:

我正在尝试创建两个函数:第一个函数将数字(也是浮点数)转换为十六进制字符串,第二个函数反之亦然。

这是我的代码:

function base10ToBase16(base10) {
  const precision = decimalsLength(base10)
  const multiplied = base10 * Math.pow(16, precision)
  const hexadecimal = multiplied.toString(16)
  
  if (isInteger(base10)) return hexadecimal
  return insertAt(hexadecimal, '.', hexadecimal.length - precision)
}

function base16ToBase10(base16) {
  const [integerPart, decimalPart] = base16.split('.')
  if (!decimalPart) return parseInt(integerPart, 16)
  return parseInt(integerPart, 16) + parseInt(decimalPart, 16) / Math.pow(16, decimalPart.length)
}

/////////////////////////
// Test
/////////////////////////
const numbers = [0, 0.5, 1, 0.8, 0.85, 0.855, 0.8555, 100, 255]
const hexes = numbers.map(n => base10ToBase16(n))
console.log(hexes)
console.log(hexes.map(h => base16ToBase10(h)))



/////////////////////////
// Utility functions
/////////////////////////
function insertAt(str, toAdd, position) {
  return `${str.slice(0, position)}${toAdd}${str.slice(position)}`
}

function isInteger(value) {
  return Number(value) === value && value % 1 === 0
}

function decimalsLength(value) {
  const [integerPart, decimalPart] = value.toString().split('.')
  return decimalPart ? decimalPart.length : 0
}

如您所见,hexesnumbers 不相等。 有没有办法做到这一点? 我阅读了this question 并尝试遵循他们的建议。

【问题讨论】:

  • 看起来你的整数工作正常,问题只出在你的浮点数上。
  • @Dshiz 你的意思是base10ToBase16 似乎有效吗?你也有一些制作作品的技巧base16ToBase10
  • base16ToBase10 正确地将整数转换回整数,但不是将浮点数转换回浮点数,正如您在其中一个结果中使用NaN 看到的那样,与原始结果相比,其他结果不正确数字。不幸的是,我对如何纠正它没有任何想法。我只是想指出这一点。
  • 其中一个问题是,当以十为底的数字小于零时,单位部分会得到一个空字符串。例如,0.5 转换为 '.8'。当您尝试将其转换回基数 10 时,parseInt('',16) 会给出NaN

标签: javascript floating-point hex


【解决方案1】:

您的base16ToBase10 很好。你的base10ToBase16 是错误的。查看 sn -p 输出。

function insertAt(str, toAdd, position) {
  return `${str.slice(0, position)}${toAdd}${str.slice(position)}`
}

function isInteger(value) {
  return Number(value) === value && value % 1 === 0
}

function decimalsLength(value) {
  const [integerPart, decimalPart] = value.toString().split('.')
  return decimalPart ? decimalPart.length : 0
}
function base10ToBase16(base10) {
  const precision = decimalsLength(base10)
  const multiplied = base10 * Math.pow(16, precision)
  const hexadecimal = multiplied.toString(16)
  
  if (isInteger(base10)) return hexadecimal
  return insertAt(hexadecimal, '.', hexadecimal.length - precision)
}

function base16ToBase10(base16) {
  const [integerPart, decimalPart] = base16.split('.')
  if (!decimalPart) return parseInt(integerPart, 16)
  return parseInt(integerPart, 16) + parseInt(decimalPart, 16) / Math.pow(16, decimalPart.length)
}

const numbers = [0, 0.5, 1, 0.8, 0.85, 0.855, 0.8555, 100, 255]
const wrong_hexes = numbers.map(base10ToBase16)
const hexes = numbers.map(n => n.toString(16))
console.log(wrong_hexes + "")
console.log(hexes + "")
console.log("hexes NOT eq wrong_hexes = ", hexes + "" !== 
wrong_hexes + "")

const roundtrip_numbers = hexes.map(base16ToBase10)
console.log(numbers + "")
console.log(roundtrip_numbers + "")
console.log("roundtrip_numbers eq numbers = ", roundtrip_numbers + "" === numbers + "")

不太确定你想用你自己的base10ToBase16 函数实现什么。你已经在里面使用了toString(16)。所以最简单的方法是改用numbers.map(n => n.toString(16))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-18
    • 2021-07-17
    • 2014-03-01
    • 2018-09-22
    • 2011-03-23
    • 2010-09-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多