在不损失精度的情况下转换浮点数的基数
术语
在这个问题中,我将“浮点数”称为“十进制数”,以防止与/ Java基元数据类型混淆。术语“十进制”与“以 10 为基数”没有关系。float
double
背景
我以这种方式表示任何基数的十进制数:
class Decimal{
int[] digits;
int exponent;
int base;
int signum;
}
它近似表示此值:double
public double toDouble(){
if(signum == 0) return 0d;
double out = 0d;
for(int i = digits.length - 1, j = 0; i >= 0; i--, j++){
out += digits[i] * Math.pow(base, j + exponent);
}
return out * signum;
}
我知道有些转换是不可能的。例如,无法转换为以 10 为基数,因为它是重复出现的小数。同样,转换为基数 3 是不可能的,但 covnerting 是可能的。可能还有其他我没有考虑过的情况。0.1 (base 3)
0.1 (base 9)
0.3 (base 3)
传统方式
对于整数,从以10为基数到以2为基数的整数,传统的(手工)变化方法是将数字除以2的指数,从基数2到基数10是将数字乘以2的相应指数。从基数 x 更改为以 y 为基数通常涉及转换为以 10 为基数作为中间值。
第一个问题:参数验证
因此,我的第一个问题是,如果我要实现该方法,我如何验证是否可以在不导致重复小数的情况下进行(这与字段的设计不兼容,因为我不打算为此制作字段。public Decimal Decimal.changeBase(int newBase)
newBase
int[] digits
int recurringOffset
第二个问题:执行
那么,如何实现这一点呢?我本能地觉得,如果第一个问题解决了,这个问题就更容易解决了。
第三个问题:重复出现的数字输出呢:
我不打算仅仅为此做一个领域。
int recurringOffset
为了未来的读者,这个问题也应该问。
例如,根据Wolfram的说法|阿尔法:
0.1 (base 4) = 0.[2...] (base 9)
如何计算(手动计算,如果通过编程听起来太复杂)?
我认为这样的数据结构可以表示这个十进制数:
class Decimal{
int[] constDigits;
int exponent;
int base;
int signum;
@Nullable @NonEmpty int[] appendRecurring;
}
例如,61/55
可以这样表示:
{
constDigits: [1, 1], // 11
exponent: -1, // 11e-1
base: 10,
signum: 1, // positive
appendRecurring: [0, 9]
}
不是家庭作业问题
我不是在寻找任何库。请不要参考任何库来回答这个问题。(因为我写这门课只是为了好玩,好吗?