Thread: float multiplication and subtraction

  1. #1
    Registered User
    Join Date
    Jun 2006
    Posts
    28

    float multiplication and subtraction

    i know this has been mentioned over and over (and over) again in this forum but i would like to ask specifically on a function i've been playing around:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    char *ftoi(float f){
        char str[20];
        char *fstr;
        float a;
       
        fstr= malloc(100);
           
        sprintf(str,"%i",(int)f); // get the int part and make it string
        strcat(fstr,str);  // store this part inside the main string
        strcat(fstr,"."); // oh, put the decimal place too
           
        f-=(int)f; // keep the part after the decimal place
       
        while(f>0){
            printf("%f\n",f); 
            f*=10;  // move the number 1 decimal place left
            printf("%f\n\n",f);
            sprintf(str,"%i",(int)f);  // make int part -> string
            strcat(fstr,str);  // store it
            f-=(int)f;      // keep only decimal 
        }
       
        printf("%s\n",fstr);   
    
         return fstr;
    }
    obviously that i want to convert float -> string.

    but then all hell breaks loose. say for f=2,55 my printf's are the following:

    Code:
    0.550000  //ok let's see
    5.500000  //so far so good
    
    0.500000  //...ok...
    4.999995  // nooooooooooo....
    
    0.999995 //&^*&^%&^&*ing ^$%#^%
    9.999952
    
    0.999952
    9.999523
    
    0.999523
    9.995232
    
    0.995232
    9.952316
    
    0.952316
    9.523163
    
    0.523163
    5.231628
    
    0.231628
    2.316284
    
    0.316284
    3.162842
    
    0.162842
    1.628418
    
    0.628418
    6.284180
    
    0.284180
    2.841797
    
    0.841797
    8.417969
    
    0.417969
    4.179688
    
    0.179688
    1.796875
    
    0.796875
    7.968750
    
    0.968750
    9.687500
    
    0.687500
    6.875000
    
    0.875000
    8.750000
    
    0.750000
    7.500000
    
    0.500000
    5.000000   // now that's funny, no 4.99 i guess it didn't have any other blocks to                    read 
    
    2.5499999523162841796875  // :-/
    most probably the problem is at the multiplication. i even tried fdimf()

    Code:
    fdimf(f,10,0) or fdimf(f, 10.0, 0)
    because of the so called "infinite precision" but i saw no change at all...
    played with doubles a bit too but nothing again...

    any suggestions on what should i do (except from messing with floats unless i'm using matlab) ?

    thank's in advance guys.

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Well, to be honest, MATLAB thinks that 2.55 is 2.5499999523162841796875 too, since floats are the same under the hood in both. (Unless MATLAB has changed since the last time I used it, which was a while ago.)

    I don't know where you're getting your numbers from; I would recommend the %g format specifier (and sprintf can print directly into a string/char array, which is handy). If you know that your numbers are supposed to be nice fractions, you could build a fraction data type. If you know a maximum number of decimal places, you could build a fixed-point data type.

  3. #3
    Registered User
    Join Date
    Jun 2006
    Posts
    28
    Quote Originally Posted by tabstop View Post
    If you know that your numbers are supposed to be nice fractions, you could build a fraction data type.
    nice fractions?

    If you know a maximum number of decimal places, you could build a fixed-point data type.
    the only thing i want to assume is float range and positive values...

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Without knowing more about what the numbers are, I can't be more specific than "nice fractions".

    Float range is a tricky thing. As you've seen, even 2.55 is not a valid floating-point value. Again, my suggestion is to use sprintf and %g.

  5. #5
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Your ftoi function if flawed in so many ways:
    1. By the name "ftoi", most would immediately assume it converts a float to an int.
    2. The design is flawed in the it will almost certainly result in memory leaks due to forgetting to free the return result. (Better to pass the buffer in instead)
    3. The function does not check the return result of malloc for NULL.
    4. Floats can store larger values than ints. Your function will fail for numbers over 11 decimal digits, which as it happens there are far more of than there are under 11 digits. E.g. 1E50
    5. Floats can store values far below 0.0000000001 it will again fail for these and produce zero. E.g. 1E-50
    6. The function fails for negative values.
    7. There are already way provided to do this which actually works. printf is one way.

    There's nothing wrong with playing around with this, but make no mistake that it should only be for learning experience. The above comments are simply to help you along in that learning.

    I happen to already have a fraction class. It can be found in the Useful Classes section of the website linked in my signature. It will even convert a float to a fraction, with pretty good accuracy.
    Last edited by iMalc; 07-16-2008 at 01:32 AM.
    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"

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. a few opengl(or general programming) questions
    By linuxdude in forum Game Programming
    Replies: 20
    Last Post: 06-14-2004, 07:47 AM
  2. Calculator in C?
    By daveS in forum C Programming
    Replies: 5
    Last Post: 08-04-2003, 10:37 AM
  3. Replies: 2
    Last Post: 05-10-2002, 04:16 PM

Tags for this Thread