如何在Javascript中将DecimalBase 10转换为小数基数即Base 3/2

问题描述

我发现很多资源都在讨论基本转换算法,并使用内置的Javascript函数将十进制转换为二进制或十六进制,但是我找不到任何有关如何转换为分数基数(例如基数3/2)的资源。 。 syquinary数字系统非常有趣,我希望能够使用它,但是我找不到从Decimal转换为它的任何方法。

亮片系统如下:1、2、20、21、22、210、211、212、2100、2101等

我无法获得任何可靠的转换方法。这是我到目前为止的代码:

function decimalToBase(number,base) {
            let digitArray = [];
            let quotient;
            let remainder;

            for (let i = 0; i < 16; i++) {
                quotient = Math.floor(number / base);
                remainder = number % base;
                digitArray.unshift(remainder);
                number = quotient;

                if (quotient == 0){
                    break;
                }
            }
            console.log(digitArray)
        }

它适用于小于10的整个底数,但是如果我输入一个分数底数(例如3/2),那么我会得到带小数的结果:

[1,0.5,1,0] // When It should be: [2,0]

任何帮助将不胜感激。

解决方法

使用以下资源...

...一个建议的解决方案是...

<html><body>
BaseHi: <input id='hi' value='3' /><br>
BaseLo: <input id='lo' value='2' /><br>
Value:  <input id='val' value='6' /><br>
<button onclick='go()'>Go!</button><br>
<br>
<br>
Result: <span id='result'></span>
<br><br>
Check: <span id='check'></span>

<script>

function decimalToBase( number,baseNum,baseDen ) {

  let digitArray = []
  digitArray[ 0 ] = number;
  let i = 0;
  
  while ( digitArray[ i ] && baseDen < digitArray[ i ] ) {
    let qi = Math.trunc( digitArray[ i ] / baseNum );
    let ri = digitArray[ i ] - qi * baseNum;
    digitArray[ i ] = ri;
    digitArray[ i + 1 ] = ( digitArray[ i + 1 ] || 0 ) + qi * baseDen;
    i++;
  }
  
  digitArray.reverse();
  return digitArray;
  
}

function go() {
  let baseHi = parseInt( document.getElementById( 'hi' ).value );
  let baseLo = parseInt( document.getElementById( 'lo' ).value );
  let value = parseInt( document.getElementById( 'val' ).value );
  if ( baseHi <= baseLo ) {
    document.getElementById( 'result' ).innerHTML = 'Error - BaseHi must be greater than BaseLo';
    return;
  }
  let result = decimalToBase( value,baseHi,baseLo );
  document.getElementById( 'result' ).innerHTML = `${value}<sub>10</sub> = ${result.join( '.' )}<sub>${baseHi}/${baseLo}</sub>`;
  
  let check = '';
  let total = 0;
  for ( let i = result.length - 1,bd = 1; 0 <= i ; i--,bd = bd * baseHi / baseLo ) {
    total += bd * result[ i ];
    check = `${result[i]}*(${baseHi}/${baseLo})<sup>${result.length - i - 1}</sup>` + ( check ? ' + ' : '' ) + check;
  }
  document.getElementById( 'check' ).innerHTML = `${check} = ${total}<sub>10</sub>`;
}
</script>
</body></html>

编辑:调整后的答案使您可以轻松测试各种基准和值,包括进行交叉检查以将新基准值反向计算回基准10。令我惊讶的是,该算法似乎在BaseLo

享受!

,

对于3/2的特殊情况,詹姆斯·普普(James Propp)的this article揭示了几种方法,其中西蒙·诺顿(Simon Norton)在 中描述的方法:

它基于这样一个事实:当n表示为3k + r时,其余r为0、1或2,则n的代表词表示等于2k的代表词表示,并加上数字r在最后。这使我们可以快速地通过反复除以三,四舍五入和加倍的过程从右向左书写n的代表词。

go read the full article

他们还提供了一些Mathematica代码来运行它。

S[n_] := If[n < 3,{n},Append[S[2 Floor[n/3]],Mod[n,3]]]

我真的不了解Mathematica,所以我真的无法在js中一对一地重写它,但是如果我正确理解算法,那将是这样的:

const decimalToSesquinary = (n) => {
  const res = [];
  while (n) {
    const k = Math.floor(n / 3);
    res.push(n % 3);
    n = k * 2;
  }
  return res.reverse().join("");
};

console.log(decimalToSesquinary(6)) // expected "210"
console.log(decimalToSesquinary(7)) // expected "211"
console.log(decimalToSesquinary(8)) // expected "212"
console.log(decimalToSesquinary(100)) // expected "212001201"

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...