The forums have permanently moved to forum.kirupa.com. This forum will be kept around in read-only mode for archival purposes. To learn how to continue using your existing account on the new forums, check out this thread.


Page 1 of 2 12 LastLast
Results 1 to 15 of 16

Thread: [C++] Truncating a Float

  1. #1

    [C++] Truncating a Float

    If you have a float in the form A.CDEFGHI, how do you truncate the end to only have three numerals: A.CD ?

    For example: I want to convert 3.5123444 to 3.51.

  2. #2
    TheCanadian's Avatar
    10,305
    posts
    Noo doot aboot it, eh?
    Code:
    Math.floor(Math.pow(10, p) * n) / Math.pow(10, p);
    //n - number to truncate
    //p - precision
    That's AS but the math is the same no matter what language you use.
    Proud Montanadian
    We tolerate living and breathing. And niches.

    Name Brand Watches

    Maybe getTimer() or TweenMax is the answer to your problem . . .

  3. #3
    Code:
    #include <math.h>
    ...
    float yourNumber = 1.23456;
    yourNumber = floor(yourNumber*100)/100;

  4. #4
    There's also setPrecision(n), but I think that's only when you're printing.

  5. #5
    Quote Originally Posted by kdd View Post
    There's also setPrecision(n), but I think that's only when you're printing.
    I'm pretty sure that rounds, not truncates. But I'm a little rusty on my C++ so I could be wrong.

  6. #6
    actionAction's Avatar
    1,142
    posts
    humanBeing._beard=true;
    floor() does round (down), and doesn't truncate. If you are wanting to perform math with a truncated number, you can try to use this method, but I don't think it will work, and it is less precise. If you are wanting to change the display of your variable, kdd was right, setprecision(n) is the way to do that, n representing the number of digits to show:

    float yourVar = 3.14159;
    cout << setprecision(2) << yourVar << endl; //Shows 3.14

  7. #7
    Quote Originally Posted by actionAction View Post
    floor() does round (down), and doesn't truncate.


    Not sure what you mean.. "rounding" down (as you put it) is truncation is it not?

    float yourVar = 3.14159;
    cout << setprecision(2) << yourVar << endl; //Shows 3.14
    But this produces the wrong output for yourVar = 3.148; It should be 3.14 if it were truncated but setprecision will round it up to 3.15.
    Last edited by Yeldarb; May 7th, 2008 at 03:19 PM.

  8. #8
    actionAction's Avatar
    1,142
    posts
    humanBeing._beard=true;
    Rounding is not the same as truncation, truncation is the severing of digits at a certain point, with no effect on the integral value of the number, whereas rounding (floor/ceil) potentially alters the integral value of the number. The difference is small, but it has a real effect on precise mathematical operations. setprecision does not alter the stored number (round or truncate), it just displays the specified number of significant digits to the right of the decimal (though I know it does round the displayed number).

    The point I was making was that NeoDreamer should leave their variable value as is, and display it with the desired precision (perhaps even using setw(n)), because flooring the number could make for less precise calculations.

  9. #9
    actionAction, how is flooring not the same as truncation? We are assuming here that the underlying hardware representation of floats is exact enough for the precision of the floats used here, right? If I truncate 3.18 to 1 decimal digits, is the result not 3.1, the same as floor(3.18 * 10)/10? What exception would there be?
    If you notice this notice you will notice that this notice is not worth noticing.

    "Are you doing anything tonight? If not, how about me?"

    Opera Sucks! - FIX IT
    Oliver Zheng

  10. #10
    Quote Originally Posted by actionAction View Post
    Rounding is not the same as truncation, truncation is the severing of digits at a certain point, with no effect on the integral value of the number, whereas rounding (floor/ceil) potentially alters the integral value of the number. The difference is small, but it has a real effect on precise mathematical operations. setprecision does not alter the stored number (round or truncate), it just displays the specified number of significant digits to the right of the decimal (though I know it does round the displayed number).

    The point I was making was that NeoDreamer should leave their variable value as is, and display it with the desired precision (perhaps even using setw(n)), because flooring the number could make for less precise calculations.
    Exactly; rounding is not the same as truncation. Which is why when he asked how to truncate a number rounding probably wasn't what he was looking for. There are many mathematical reasons where he may want to truncate a number rather than round it.

    It's only "less accurate" if you assume that he's just trying to display the full precision number to a certain number of decimal places. If he wants to do computation with a truncated number, the *only* accurate answer is gotten by truncating (whether it is via flooring a float or casting to an integer is not really relevant).
    Last edited by Yeldarb; May 8th, 2008 at 03:55 AM.

  11. #11
    actionAction's Avatar
    1,142
    posts
    humanBeing._beard=true;
    First, I am not trying to stir the pot, as it were; nor do I mean any offense.

    What exception would there be?
    @MT: It depends on the arguments supplied, -3.18 for instance, floors to -3.2, and truncates to -3.1. FLOOR does truncate and is equivalent to TRUNC on positive arguments, CEIL is equivalent to TRUNC on negative arguments, but what each of these functions truncates towards is the important distinction. Floor truncates toward negative infinity, CEIL truncates toward positive infinity, and actual TRUNC functions truncate toward zero. Using these functions interchangeably (without knowing for sure if you are dealing with exclusively positive digits) will produce inaccurate results.

    @Yeldarb: I was simply saying it is more accurate to use the full precision number for operations, and only to truncate the displayed number. Obviously if NeoDreamer wants to do calculations with a truncated number, they should use a truncated number.

    I retract my statement that floor doesn't truncate, I don't know why I said that.
    Last edited by actionAction; May 8th, 2008 at 01:20 PM.

  12. #12
    I'm not sure but I think that behavior is undefined in the C++ spec (in terms of truncation on integer division); it may be compiler/processor dependent.

  13. #13
    actionAction's Avatar
    1,142
    posts
    humanBeing._beard=true;
    Quote Originally Posted by Yeldarb View Post
    I'm not sure but I think that behavior is undefined in the C++ spec (in terms of truncation on integer division); it may be compiler/processor dependent.
    It could very well be compiler specific (VS2005 Pro on my end). The funny part about this discussion is that there really is no trunc function inherent to C++, so one would most likely be relegated to using float or ceil in a conditional (negative or positive) like this:
    Code:
    double fakeTRUNC(double n, double p = 1)
    {
        if(n > 0)
        {
            double val = (pow(10,p)) * n;
            floor(val);
            val /= pow(10,p);
            return val;
        }
        else
        {
            double val = (pow(10,p)) * n;
            ceil(val);
            val /= pow(10,p);
            return val;
        }
    }
    But here is a trunc function that uses modf to actually truncate:
    Code:
    double TRUNC(double value, int decimal_places)
    {
        double integer = 0,
               fractional = 0,
               output = 0;
    
        int j = 0,
            places = 1;
    
        fractional = modf(value, &output);
        for( int i = 0; i < decimal_places + 1; i++ )
        {
            fractional = modf(fractional, &integer);
            for( j = 0; j < i; j++ )
            {
                places *= 10;
            }
            output += integer / places;
            places = 1;
            fractional *= 10;
        }
        return output;
    }

  14. #14
    Haven't tried it, but perhaps just an integer type conversion could help?

    float pi = 3.1415926;

    float pi2 = (float)((int)(pi*100)/100);

    (The above may be incorrect, but the point is to create an integer with two extra decimals, and it will simply discard anything after the floating point - just reverse it again, and you would have a truncated number)
    Last edited by Surrogate; May 27th, 2008 at 08:10 PM.
    ipwn | Coming soon

  15. #15
    Quote Originally Posted by NeoDreamer View Post
    If you have a float in the form A.CDEFGHI, how do you truncate the end to only have three numerals: A.CD ?

    For example: I want to convert 3.5123444 to 3.51.
    This is quite simple really using basic knowledge of C.

    1. shift decimal place 2 places to right (i.e. multiply by 100).
    2. cast it to an int to get rid of the rest of the digits after to decimal point
    3. divide by 100 to shift the decimal place back 2 places to the left

    Note that the lvalue (fVal) must obviously be a float!
    e.g.
    float fVal = 3.5123444;
    fVal = (int) (fVal * 100.0f) / 100.0f;


Page 1 of 2 12 LastLast

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

Home About kirupa.com Meet the Moderators Advertise

 Link to Us

 Credits

Copyright 1999 - 2012