Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Own Big Float in C++

Tags:

c++

I want to write my own variable "type" as a homework in C++. It should be an arbitrarily long float. I was thinking of structure like...

Code:

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
};

Where if i have number like: 3.1415 Before = '3'; after = '1415'; pos = 1; If that makes sense to you... BUT assignment wants me to save some memory, which I don't because for every number I allocate about it is about 1 byte, which is too much I guess.

Question:

How would you represent those arbitrarily long numbers? (Sorry for my bad english, I hope the post makes sense)

like image 504
tyrhus Avatar asked May 19 '13 19:05

tyrhus


People also ask

How do you store large float values?

The answer to the question of what is the largest (finite) number that can be stored in a floating point type would be FLT_MAX or DBL_MAX for float and double , respectively.

Is there long float in C?

The long float is a K&R C first edition type that existed. It is synonymous with double . After the first standard C89/C90, long float is removed. It is not deprecated.

Is C float 32 or 64?

float is a 32-bit IEEE 754 single precision Floating Point Number – 1 bit for the sign, 8 bits for the exponent, and 23* for the value. float has 7 decimal digits of precision.

What is a float in C?

In C float is a data type that represents floating point numbers, using 32 bits. We use this type more often than double, because we rarely need the double’s precision.

What are floating point numbers in C++?

Floating-point numbers are used for decimal and exponential values. For example, // creating float type variables float num1 = 3.0f; float num2 = 3.5f; float num3 = 3E-5f; // 3x10^-5 // creating double type variables double num4 = 3.0; double num5 = 3.5; double num6 = 3E-5; // 3x10^-5. We must add the suffix f or F at the end of a float value.

Can I use float instead of double in C++?

In this case, 5.6 is converted to float by the compiler automatically before it is assigned to the variable a. This may result in data loss. To learn more, visit C++ Type conversion. Note: Unless you have a specific requirement, always use double instead of float, as float variables may be prone to introduce errors when working with large numbers.

What is single precision (float) in C++?

According to it, the single precision (float) is represented by 32 bits as follows: This allows you to save up to 8 digits, including to the left and right of the fraction delimiter. As you can see in the example above ( source on GitHub ), the following values can be saved without a problem


1 Answers

If you need to preserve memory, all that means is that you need to use memory as efficiently as possible. In other words, given the value you're storing, you shouldn't waste bytes.

Example:

  1. 255 doesn't need 32 bits

I think your vector of chars is fine. If you're allowed to use a C++11 compiler, I'd probably change that to a vector of uint8_t and make sure when I'm storing the value that I can store a value from 0 to 255 in a vector of size 1.

However, that's not the end of it. From the sounds of it, what you're after is an arbitrary number of significant digits. However, for a true float representation, you also need to allocate storage for the base and exponent, after deciding what the base will be for your type. There is also the question of whether you want your exponent to be arbitrarily long too. Let's assume so.

So, I'd probably use something like this for members of your class:

//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;

It is then a matter of implementing the various operators for your type and testing various scenarios to make sure your solution works.

If you really want to be thorough, you could use a simple testing framework to make sure that problems you fix along the way, stay fixed.

In memory, it will essentially look like a binary representation of the number.

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>

As others have mentioned, you don't really need two vectors for before and after the decimal. However, I'm using two in my answer because it makes it easier to understand and you don't have to keep track of the decimal. The memory requirements of two vs one vector really aren't that different when you're dealing with a long string of digits.

I should also note that using an integer to record position of the decimal point limits your number of digits to 2 billion, which is not an arbitrarily long number.

UPDATE: If this actually is homework, I would check with whoever has given you the homework if you need to support any floating point special cases, the simplest of which would be NaNs. There are other special cases too, but trying to implement all of them will very quickly turn this from a homework assignment into a thesis. Good luck :)

like image 198
Carl Avatar answered Nov 14 '22 23:11

Carl