Thread: Why so much trouble with floating points?

  1. #1
    Registered User darketernal's Avatar
    Join Date
    Sep 2001
    Posts
    41

    Why so much trouble with floating points?

    (I use borland c++ builder 5)



    Lets say i want the number 1 devided by 4 = 0.25
    i want my CSpinEdit to display this number.

    So i tried CSpinEdit1->value = 0.25.

    It doesn't work, my question is where do i find a cspinedit (or any other component) that supports large numbers of floating points? I tried BMSpinEdit, but it only supports 6 digits, my calculations go beyond it.

  2. #2
    Reverse Engineer maxorator's Avatar
    Join Date
    Aug 2005
    Location
    Estonia
    Posts
    2,318
    Maybe use standard functions?
    Like sprintf() or std:: stuff.
    "The Internet treats censorship as damage and routes around it." - John Gilmore

  3. #3
    Registered User darketernal's Avatar
    Join Date
    Sep 2001
    Posts
    41
    The main consern is how to translate that into a floating value that gets displayed in spinedit?

  4. #4
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Like maxorator suggests, you may want to convert the floating point to a string first, then display it.

  5. #5
    Registered User
    Join Date
    May 2006
    Posts
    903
    float foo = 1;
    std::stringstream ss;
    ss << (foo / 4);

    ss.Str(); // returns an std::string
    ss.Str().c_str(); // returns a const char*

  6. #6
    Registered User darketernal's Avatar
    Join Date
    Sep 2001
    Posts
    41
    Ok, this stuf compiles in Borland builder

    Edit1->Text = FloatToStr(1/5);

    but the devision doesn't work.

    if you say Edit1->Text = FloatToStr(1 - 0.34343);

    the calculation does work.

    Its vital that i can divide. Why doesn't it work?

  7. #7
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    1 is an integer. So is 5. If you want floating point division, you have to mark the number as a floating point type. By default, floating point numbers use double in C++, so if you used 1.0 and 5.0 instead that would make them doubles and the division would work.

  8. #8
    Registered User darketernal's Avatar
    Join Date
    Sep 2001
    Posts
    41
    I want to thank you from the bottom of my heart,as it works -_-

    It feels unnatural tho because every calculator on the planet can give a 1/5 = 0.2 result.

    Am i wrong for thinking that such a basic calculation should also be possible with borland, regardless wether you'd be using an integer or not?

  9. #9
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    But dividing integers is a valid thing to do as well. If you are just doing integer arithmetic, you don't want something like 0.2. How does the compiler know the difference?

    The designers of the language decided to identify which is which based on the types of the operands. Since 1 and 5 are ints, it does integer division. The calculator just assumes you always want floating point arithmetic and doesn't give you the choice, which is why it "works" there.

  10. #10
    Registered User darketernal's Avatar
    Join Date
    Sep 2001
    Posts
    41
    Anyway my list of problems doesn't seem to end.

    im calculating 1.0/54.0 = 0.0185185185185185185 = not correct

    Your ordinairy windows calculator would give 1/54 =

    0.018518518518518518518518518518519

    A longer number, i need to increase the amount of decimals displayed. I can't have any round off calculations, its important that it needs to be exactly like the number the windows calculator displays.

  11. #11
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    You need more precision. Unfortunately, it sounds like windows calculator provides more precision than the standard floating point types in C++. You should try it with long double instead of float, but I'm not sure about the Borland code you are using and how well it supports other types, and I get the feeling that the result will not be precise enough anyway. (BTW, for long double it would be 1.0L/5.0L).

    In the end, if you really think you'll need larger precision, then you'll probably have to use a library that supports it. I think GMP might be one, but you can search for high precision floating point libraries.

    >> I can't have any round off calculations
    Windows calculator does rounding, it just does it later than the code you are using. You have to have rounding.

  12. #12
    Registered User darketernal's Avatar
    Join Date
    Sep 2001
    Posts
    41
    Ok, i've been messing around, but even the extended doesn't give more then 0.0185185185185185185

    You know you have the FloatToDecimal function.

    The Decimals parameter specifies the requested maximum number of digits to the left of the decimal point in the result. Precision and Decimals together control how the result is rounded. To produce a result that always has a given number of significant digits regardless of the magnitude of the number, specify 9999 for the Decimals parameter.

    extern PACKAGE void __fastcall FloatToDecimal(TFloatRec &Result, const void *Value, TFloatValue ValueType, int Precision, int Decimals);

    I have no idea how to use FloatToDecimal tho , So im wondering if it is possible to get a larger number out of FloatToDecimal , i've looked into your GMP suggestion, but it seems that library is rather Unix based then towards the windows enviroment im using (xp) , so if possible id like to go around that , and although not excluding any possibility, i would have hoped to get this larger decimal out of FloatToDecimal,

    I can't find any good FloatToDecimal examples which could expand the number.

    Im not picky i'll try any method that will give the 1/54 =

    0.018518518518518518518518518518519 result.

  13. #13
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    But 1/54 is a recurrent decimal anyway.

    The result being 0.0185185185185185185 and so on and so on. After you've printed 3 or 4 repeats, it gets pretty meaningless anyway.

    > Im not picky i'll try any method that will give the 1/54 =
    > 0.018518518518518518518518518518519 result.
    Well it's not going to happen with any data type you're going to find on a PC without some help from a library.

    A double has a precision of 15 decimal digits, so if you use any standard functionality, you get something like this.
    Code:
    #include <stdio.h>
    
    int main ( ) {
        double f = 1.0 / 54.0;
        long double g = 1.0l / 54.0l;
        printf("%.15f\n", f );
        printf("%.20f\n", f );
        printf("%.18Lf\n", g );
        printf("%.25Lf\n", g );
        return 0;
    }
    $ ./a.exe
    0.018518518518519
    0.01851851851851851749
    0.018518518518518519
    0.0185185185185185185188322
    In other words, trying to print anything beyond the precision of the underlying floating point format will just get you random noise.
    A long double will get you another 3 decimal digits, but that's still way off the 30+ digits you seem to want.

    Perhaps read up on what float can and cannot do, rather than basing your expectations on observation of windows calc.exe
    http://en.wikipedia.org/wiki/Floating_point
    http://docs.sun.com/source/806-3568/ncg_goldberg.html
    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.

  14. #14
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by darketernal View Post
    Anyway my list of problems doesn't seem to end.

    im calculating 1.0/54.0 = 0.0185185185185185185 = not correct

    Your ordinairy windows calculator would give 1/54 =

    0.018518518518518518518518518518519

    A longer number, i need to increase the amount of decimals displayed. I can't have any round off calculations, its important that it needs to be exactly like the number the windows calculator displays.
    Impossible. Without the source code to the Windows calculator, there is no way to be absolutely sure that in EVERY case the output is identical.
    Don't forget, the Windows calculator suffers from inaccuracy just like every other calculator.
    See what happens if you evaluate (2^0.5)^2 - 2 (where ^ signifies to-the-power-of). Note, the correct answer is zero.
    The calculator can't represent every possible answer. It sure as hell can't represent numbers such as PI to infinite precision either!

    Please state the reasons you would think you need it to be identical to the Windows calculator, and perhaps we can debunk a few myths for you.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  15. #15
    Registered User darketernal's Avatar
    Join Date
    Sep 2001
    Posts
    41
    ok, i founded a fitting solution. It seems that it all has to do with the value that is stored in the memory of the computer.

    if in Borland i would use a floating point 1/255 = 0.00392156862745098

    In windows calculator the result would be1/255 = 0.003921568627450980392156862745098

    So i was thinking Lets recalculate (using windows calculator by saying 1/255 = 0.003921568627450980392156862745098 * 255 = 1

    Borland would give. 255 * 0.00392156862745098 = 0.9999999999999999

    You see, i had to get the value back on a solid 1 like in the windows calculator,instead of 0.99999999999999 this is why i was begging for more digits thinking it was a solid number, until someone pointed out that the number too was infinite , i didn't notice until then that the value gets stored in a odd manner.

    For example.

    If in (windows calculator) you say 1/255 = 0.003921568627450980392156862745098 * 255 = 1. This made me believe that it was an accurate number but its not, if you try typing

    0.003921568627450980392156862745098 * 255 = (in your windows calculator) you get: 0.999999999999999999999999999975

    So in order to get the accurate value, i basically applied the same trick as the windows calculator used by going backwards after going forward in Borland by using the same stored value to calculate instead of calculating with a result value i got the number 1 as i desired.

    The windows calculators behaviour was basically the behaviour i desired for my program and i managed to do that so with this.

    Thanks everyone. =)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. help! calculate arbitrary number of floating points
    By cakestler in forum C Programming
    Replies: 5
    Last Post: 02-26-2009, 02:47 PM
  2. Help it won't compile!!!!!
    By esbo in forum C Programming
    Replies: 58
    Last Post: 01-04-2009, 03:22 PM
  3. Replies: 8
    Last Post: 11-03-2008, 09:48 PM
  4. Yahtzee C++ programme help
    By kenneth_888 in forum C++ Programming
    Replies: 13
    Last Post: 09-05-2007, 02:14 PM
  5. CProg Fantasy Football version pi
    By Govtcheez in forum A Brief History of Cprogramming.com
    Replies: 155
    Last Post: 12-26-2006, 04:30 PM