# Math help: describing the fractional part of a floating-point

• 07-10-2006
Mario F.
Math help: describing the fractional part of a floating-point
I need help with the math needed to describe the fractional part of a floating-point number after applying modf().

Namely, I want the fractional part to be described with two ints. One representing the fractional portion, and the other a base 10 exponent.

Code:

```float is 123.0450 int integer = 123; // I get this one with modf() int frac = 450;    // I get this one as 0.0450 with modf(). int exp = -4; The float is thus described with 3 ints: integer + frac * 10^exp```
How can I produce frac and exp.
• 07-10-2006
King Mir
Well for double, the lowest possible fraction is 2.2 × 10^-308.

So you could do this:
Code:

```double mydouble=123.0450; double integer; int exp = 308; int frac=fmod(mydouble,*integer)*pow(10,308) while(!(frac%10))     --exp, frac/10;```

Not sure that would be precise though. You might loose something working with powers of 10.

Edit: edited to be valid
• 07-10-2006
Mario F.
Hmm... close! Very close. Got the logic. :)
But unfortunatley can't modulus a non integral type. But I can work from here... I think
• 07-10-2006
King Mir
The other way to do it is to take the return value of fmod, and take the value apart. That is using bitwise opperators seperate the exponent and significand, then convert from base two to base ten. This is bound to be more accurate, but also harder.

It would also be non-C++ standard, and you might run into problems with Big Endian vs Little Endian notation.
• 07-10-2006
Mario F.
I can work with your initial example. Thanks a bunch King.

Off the top of my head will be something like this:

Code:

```double frac = modf(value, integer); while(frac * 10 < 1)     --exp, frac*=10; Once this portion finishes I can loop further testing for !modf(frac)```
This is to be implemented on a simple set of classes to work with fixed precision floating point numbers.

Your help was precious. Thanks again
• 07-10-2006
kuphryn
Interesting.

int i = 1;
double x = 1.234,
y = (x * static_cast<double>(pow(10, i)));

while ((y - floor(y)) > 0.0)
y = (x * static_cast<double>(pow(10, ++i)));

y -= (floor(x) * pow(10, i));

Kuphryn
• 07-10-2006
King Mir
• 07-11-2006
Salem
So what's the difference between
int frac = 450;
int exp = -4;

and
int frac = 45;
int exp = -3;

or even
int frac = 45000;
int exp = -6;

Not all fractions are going to end in repeating zero, so what are you going to do in those situations?

Did you get to 123.0450 by dividing by some integer to start with?
• 07-11-2006
jafet
Probably normalize them. Just divide by ten continuously.

45000, -6
== 4500, -5
== 450, -4
== 45, -3

45 is not divisible by ten so we stop. Hope I make sense.

Quote:

Not all fractions are going to end in repeating zero, so what are you going to do in those situations?
Well, depends. I figure it'd be enough to keep say the last X digits or so. If you want more precision just use GMP or something.
• 07-11-2006
Mario F.
Well, I'm still on the planning phase.

The idea is to accept a double into the class constructor. The class itself will implement some form of naive floating-points; a fixed precision floating point replacement for floating-point numbers that can be safely used with logical operators. I'm aware there's lots of this out there. But I feel like reinventing the wheel and making my own. ;)

However, after sleeping over it, I think constructing the class out of a double is a bad idea. I'll be carrying over into the constructor all the "problems" associated with this type. For instance, what if I obtained the class constructor argument through 1 / 3? Suddenly a std::string becomes a more appealing option. However it's very unnatural.

On the other hand I can simply force a fixed precision at the head of the constructor, discarding anything to the right. Or allow the constructor to accept a second integer argument (with a default value) which will allow the user to specify the precision they want to work with.

For all that matters, kuphryn's option is more elegant.