8

我想用 C++ 编写自己的变量“类型”作为家庭作业。它应该是一个任意长的浮点数。我在想像这样的结构......

代码:

class bigFloat
{
public:
    bigFloat(arguments);
    ~bigFloat();

private:
    std::vector<char> before; // numbers before decimal point
    std::vector<char> after; // numbers after decimal point
    int pos; // position of decimal point
};

如果我有这样的数字:3.1415 Before = '3'; 之后 = '1415'; 位置 = 1; 如果这对你有意义...但是分配希望我节省一些内存,我不这样做,因为我分配的每个数字大约是 1 个字节,我猜这太多了。

问题:

你将如何表示这些任意长的数字?(对不起我的英语不好,我希望这篇文章有意义)

4

2 回答 2

4

如果您需要保留内存,这意味着您需要尽可能有效地使用内存。换句话说,给定您存储的值,您不应该浪费字节。

例子:

  1. 255 不需要 32 位

我认为您的字符向量很好。如果您被允许使用 C++11 编译器,我可能会将其更改为uint8_t的向量,并确保在存储值时可以将 0 到 255 的值存储在大小的向量中1.

然而,这还不是结束。从它的声音来看,您所追求的是任意数量的有效数字。但是,对于真正的浮点表示,在确定类型的基数之后,您还需要为基数和指数分配存储空间。还有一个问题是您是否希望您的指数也可以任意长。让我们假设是这样。

所以,我可能会为你的班级成员使用这样的东西:

//Assuming a base of 10.
static uint8_t const base = 10;
std::vector<uint8_t> digits_before_decimal;
std::vector<uint8_t> digits_after_decimal;
std::vector<uint8_t> exponent;
std::bitset<1> sign;

然后是为您的类型实现各种运算符并测试各种场景以确保您的解决方案有效的问题。

如果您真的想要彻底,您可以使用一个简单的测试框架来确保您在此过程中修复的问题保持不变。

在内存中,它基本上看起来像是数字的二进制表示。

For example:
65535 will be: before_decimal =<0xff,0xff>, after_decimal vector is empty
255.255 will be: before_decimal =<0xff>, after_decimal=<0xff>
255255 will be: before_decimal =<0x03,0xe5,0x17>, after_decimal vector is empty
255255.0 will be: before_decimal =<0x03,0xe5,0x17>, after_decimal: <0>

正如其他人所提到的,您实际上并不需要小数点前后的两个向量。但是,我在答案中使用了两个,因为它更容易理解,而且您不必跟踪小数点。当您处理一长串数字时,二对一向量的内存需求实际上并没有那么不同。

我还应该注意,使用整数来记录小数点的位置会将您的位数限制为 20 亿,这不是一个任意长的数字。

更新:如果这实际上是作业,如果您需要支持任何浮点特殊情况,我会与给您作业的人核实,其中最简单的是 NaNs。还有其他特殊情况,但尝试全部实现它们会很快将其从家庭作业变成论文。祝你好运 :)

于 2013-05-19T20:15:24.420 回答
2
  1. 不要使用两个单独的向量beforeafter。您需要整个尾数来进行算术运算。

  2. 实际上你pos是指数。相应地命名它。指数是有符号的。

  3. 你需要尾数的符号。

  4. 我建议将尾数存储为有理分数。你需要两个数字:分子和分母。然后你可以在没有四舍五入的情况下进行除法。

  5. 最好将数字存储为具有任意长度的整数而不是数字数组。


PS。我很久以前就做过这样的计算器。为了说明我的回答,我给你声明数字的类:

class CNumber
{
// ctors, methods....
   char cSign; // sign of mantissa
   CString strNumer; // numerator of mantissa
   CString strDenom; // denominator of mantissa
   char cExpSign; // sign of exponent
   CString strExp; // exponent
};

我用过MFC。CString 是那里的标准字符串。

于 2013-05-19T20:57:21.437 回答