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

  1. #1
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446

    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.
    Last edited by Mario F.; 07-10-2006 at 07:38 PM.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  2. #2
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    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
    Last edited by King Mir; 07-10-2006 at 09:39 PM.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  3. #3
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Hmm... close! Very close. Got the logic.
    But unfortunatley can't modulus a non integral type. But I can work from here... I think
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  4. #4
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    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.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  5. #5
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    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
    Last edited by Mario F.; 07-10-2006 at 08:25 PM.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  6. #6
    Registered User
    Join Date
    Nov 2001
    Posts
    1,348
    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

  7. #7
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Your welcome, glad to help.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    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?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    Registered User
    Join Date
    Mar 2006
    Posts
    725
    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.

    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.
    Code:
    #include <stdio.h>
    
    void J(char*a){int f,i=0,c='1';for(;a[i]!='0';++i)if(i==81){
    puts(a);return;}for(;c<='9';++c){for(f=0;f<9;++f)if(a[i-i%27+i%9
    /3*3+f/3*9+f%3]==c||a[i%9+f*9]==c||a[i-i%9+f]==c)goto e;a[i]=c;J(a);a[i]
    ='0';e:;}}int main(int c,char**v){int t=0;if(c>1){for(;v[1][
    t];++t);if(t==81){J(v[1]);return 0;}}puts("sudoku [0-9]{81}");return 1;}

  10. #10
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    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.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. checking for floating point number
    By ssharish2005 in forum C Programming
    Replies: 6
    Last Post: 10-18-2005, 08:14 PM
  2. Floating point #'s, why so much talk about it?
    By scuzzo84 in forum C Programming
    Replies: 5
    Last Post: 09-20-2005, 04:29 PM
  3. floating point variables in edittext controls
    By dootickle in forum Windows Programming
    Replies: 3
    Last Post: 04-15-2004, 11:15 AM
  4. Floating point numbers in a binary file
    By frenchfry164 in forum C++ Programming
    Replies: 6
    Last Post: 07-31-2003, 10:04 AM
  5. Illegal use of floating point...(In C)
    By OmnipotentCow in forum C Programming
    Replies: 5
    Last Post: 05-31-2003, 06:26 PM