2013-10-04 46 views
0

我试图在.NET中创建一个“BigDouble”结构。 BigDouble数字有一个BigInteger组成部分和一个小数部分。乘以两个BigDouble值

执行加法和减法很简单,但我该怎么做乘法/除法?问题是,我无法找到一种将BigInteger与double相乘的方法。我该怎么办?

请记住:我需要一个确切的楼层和一个近似的小数部分。

+0

对不起,你不能乘以一个BigInteger和一个double,并得到一个精确的整数部分。我们不能总是有我们想要的。 – 2013-10-04 13:54:35

+0

您可以将double转换为2 ** x *(a/b),其中x,a和b是适当大小的整数,然后从那里继续。 –

+4

我应该告诉你,这根本不是一个好主意。你似乎对双重结构以及它是如何工作有一个基本的误解。双精度表示一个适合其大小的粒度值。通过将其固定为1的分数,您只需简单地丢弃double的幅度分量即可。由于你的小数部分始终是一个设定的magness,所以使用另一个整数类型值(无符号)。它的代表值将是该值除以该整数的最大值。根据您的小数分量的需要,这会给您的值介于0和1之间。 –

回答

0

A double具有固定数量的mantiassa比特和指数。根据IEEE规范,mantiassa将有52位,并且小数点之前的bis被忽略,但总是为1.因此,实际上至少有53位信息超过小数点。如果幸运的话,小数部分很小,那么可能会有更多的分辨率,但如果积分部分不为零,这似乎不太可能。

因此,一种解决方案将小数部分乘以2并将其四舍五入为整数。然后,您可以使用这些缩放值进行计算,使用它们形成更大的整数,然后缩小。如果您希望不惜一切代价避免数据丢失,则必须确定double号码的指数并相应地进行缩放。我知道其他语言的一些功能,如Java中的Math.getExponent或C中的ilogb。我猜测在.net中有类似的东西,但我不知道它。

但是,这整个观察告诉我(也可能告诉你),double可能不是存储小数部分的适当方式。 double的优势在于它的浮点数:您可以使用不断变化的指数存储极小值和极大值。然而,在你的应用程序中,你将以大约相等的概率存储范围[0,1)的值(或者我假设)。因此double的主要优势没有被使用。我想你可能会更好使用基于BigInteger的固定精度。我建议使用小数点后的64位。存储要求将与您的方法相同,因为double需要64位。但在大多数情况下,准确度会提高大约11位,因为您可以使用全部64位的有用数字,而不是您的方法只有53位。性能也会好很多,因为你不必在格式之间进行转换。