将小数转换为混合基数(基数)
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)
【讨论】:
以上是关于将小数转换为混合基数(基数)的主要内容,如果未能解决你的问题,请参考以下文章