将小数转换为混合基数(基数)

Posted

技术标签:

【中文标题】将小数转换为混合基数(基数)【英文标题】:Converting a decimal to a mixed-radix (base) number 【发布时间】:2009-04-17 06:55:56 【问题描述】:

如何将十进制数转换为mixed radix 表示法?

我猜给定一个包含每个基数的数组的输入和十进制数,它应该输出一个包含每列值的数组。

【问题讨论】:

【参考方案1】:

伪代码:

bases = [24, 60, 60]
input = 86462                       #One day, 1 minute, 2 seconds
output = []

for base in reverse(bases)
    output.prepend(input mod base)
    input = input div base          #div is integer division (round down)

【讨论】:

【参考方案2】:

数字 -> 集合:

factors = [52,7,24,60,60,1000]
value = 662321
for i in n-1..0
  res[i] = value mod factors[i]
  value = value div factors[i]

反过来:

如果您有 32(52)、5(7)、7(24)、45(60)、15(60)、500(1000) 之类的数字,并且希望将其转换为十进制:

取数n,乘以n-1的因数,继续n-1..n=0

values = [32,5,7,45,15,500]
factors = [52,7,24,60,60,1000]

res = 0;
for i in 0..n-1
  res = res * factors[i] + values[i]

你有号码。

【讨论】:

问题要求与此相反。【参考方案3】:

Java 你可以这样做

public static int[] Number2MixedRadix(int[] base, int number) throws Exception 
            //NB if the max number you want @ a position is say 3 then the base@ tha position
            //in your base array should be 4 not 3

            int[] RadixFigures = new int[base.length];
            int[] PositionPowers = new int[base.length];
            PositionPowers[base.length-1] = 1;
            for (int k = base.length-2,pow = 1; k >-1; k--)
                pow*=base[k+1];
                PositionPowers[k]=pow;
            for (int k = 0; k<base.length; k++)
                RadixFigures[k]=number/PositionPowers[k];
                if(RadixFigures[k]>base[k])throw new Exception("RadixFigure@["+k+"] => ("+RadixFigures[k]+") is > base@["+k+"] => ("+base[k]+") | ( number is Illegal )");
                number=number%PositionPowers[k];
            return RadixFigures;
        

示例

//e.g. mixed-radix base for 1day
int[] base = new int[]1, 24, 60, 60;//max-day,max-hours,max-minutes,max-seconds
int[] MixedRadix = Number2MixedRadix(base, 19263);//19263 seconds
//this would give [0,5,21,3] => as per 0days 5hrs 21mins 3secs

反转

 public static int MixedRadix2Number(int[] RadixFigures,int[] base) throws Exception 
            if(RadixFigures.length!=base.length)throw new Exception("RadixFigures.length must be = base.length");
            int number=0;
            int[] PositionPowers = new int[base.length];
            PositionPowers[base.length-1] = 1;
            for (int k = base.length-2,pow = 1; k >-1; k--)
                pow*=base[k+1];
                PositionPowers[k]=pow;
            for (int k = 0; k<base.length; k++)
                number+=(RadixFigures[k]*PositionPowers[k]);
                if(RadixFigures[k]>base[k])throw new Exception("RadixFigure@["+k+"] => ("+RadixFigures[k]+") is > base@["+k+"] => ("+base[k]+") | ( number is Illegal )");
            return number;
        

【讨论】:

【参考方案4】:

我想出了一个稍微不同的方法,可能不如这里的其他方法好,但我想我还是要分享一下:

    var theNumber = 313732097; 
    
    //             ms   s   m   h    d
    var bases = [1000, 60, 60, 24, 365];
    var placeValues = [];  // initialise an array
    var currPlaceValue = 1;
    
    for (var i = 0, l = bases.length; i < l; ++i) 
        placeValues.push(currPlaceValue);
        currPlaceValue *= bases[i];
    
    console.log(placeValues);
    // this isn't relevant for this specific problem, but might
    // be useful in related problems.
    var maxNumber = currPlaceValue - 1;
    
    
    var output = new Array(placeValues.length);
    
    for (var v = placeValues.length - 1; v >= 0; --v) 
        output[v] = Math.floor(theNumber / placeValues[v]);
        theNumber %= placeValues[v];
    
    
    console.log(output);
    // [97, 52, 8, 15, 3] --> 3 days, 15 hours, 8 minutes, 52 seconds, 97 milliseconds

【讨论】:

我认为您可以在第二个循环中使用 Math.DivRem。 output[v]=Math.DivRem(theNumber,placeValues[v],out theNumber);【参考方案5】:

我之前尝试了一些示例,发现了一个他们没有涵盖的边缘情况,如果你最大化你的规模,你需要在最后一步的结果之前添加

def intToMix(number,radix=[10]):
    mixNum=[]

    radix.reverse()
    for i in range(0,len(radix)):
        mixNum.append(number%radix[i])
        number//=radix[i]
    mixNum.append(number)
    mixNum.reverse()
    radix.reverse()
    return mixNum


num=60*60*24*7

radix=[7,24,60,60]

tmp1=intToMix(num,radix)

【讨论】:

以上是关于将小数转换为混合基数(基数)的主要内容,如果未能解决你的问题,请参考以下文章

小数的二进制补码

如何将数值转化为二进制数?

组成原理中关于小数和整数关于十,二,十六,八进制之间任意的转换

《程序是怎样跑起来的》第三章

二进制小数和IEEE浮点标准

将代码从5位转换为3位字符