Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site











SourceForge.net Logo

About rounding double values

Standard C math library defines two rounding functions:

 

floor - rounds to the nearest non-greater float without decimal digits, i.e.

 

floor(-2.8) = floor(-2.4) = -3, floor(8) = floor(8.2) = floor(8.8) = 8

 

ceil - rounds to the nearest non-lower float without decimal digits, i.e.

 

ceil(-2.8) = ceil(-2.4) = -2, ceil(8.2) = ceil(8.8) = ceil(9) = 9

 

In addition to these standard functions, U++ defines (in Core/util.h) a few of its own:

 

int fround(double x);

int ffloor(double x);

int fceil(double x);

 

These combine rounding (to the nearest integer, to the nearest non-greater, to the nearest non-lower integer, respectively) with truncation of float to integer.

 

int ilog10(double d);

double ipow10(int i);

double normalize(double d, int& exponent);

 

These functions can be used to manipulate the order magnitude of floats. ilog10 returns the greatest integer i such that 10^i <= d, ipow10 calculates 10^i (should be relatively fast, at least for reasonable exponents), normalize transforms a float d to the form mantissa * 10^exponent, where mantissa (the returned double) lies in the semi-closed interval [1, 10).

 

double roundr(double d, int digits);

double floorr(double d, int digits);

double ceilr(double d, int digits);

 

These functions round given float to the given number of __valid__ digits (i.e. relative to its magnitude).

 

All in all, the simple rounding you are asking for is currently not present, but it's relatively easy to implement, e.g.:

 

round(d, n) = floor(d / ipow10(n) + 0.5) * ipow10(n)

 

But your example (where you are using the rounding function to initialize an edit field), is still something a bit different, what you are demonstrating here is formatting a float to the given number of digits. If you look into Core/Format.h, you'll find the following functions:

 

enum

{

    FD_SIGN     = 0x01, // always prepend sign (+10)

    FD_REL      = 0x02, // relative decimal places (valid digits)

    FD_SIGN_EXP = 0x04, // always prepend sign to exponent (1e+2)

    FD_CAP_E    = 0x08, // capital E for exponent (1E10)

    FD_ZERO     = 0x10, // keep trailing zeros (1.25000)

    FD_FIX      = 0x20, // always use fixed notation (FormatDouble)

    FD_EXP      = 0x40, // always use exponential notation (FormatDouble)

};

String         FormatDoubleDigits(double d, int digits, int flags, int& exponent);

String         FormatDouble(double d, int digits, int flags = 0, int fill_exp = 0);

String         FormatDoubleFix(double d, int digits, int flags = 0);

String         FormatDoubleExp(double d, int digits, int flags = 0, int fill_exp = 0);

 

You can use these to perform almost any imaginable (reasonable) float formatting. For a start try FormatDouble(x, digits), I suppose this should do something similar to your MyRoundDouble.

 

There's still another option using EditDouble. It has a method called Pattern, which sets the formatting string for NFormat which is used to generate the textual representation of the number. To round to a fixed number of decimal digits, use e.g.

 

EditDouble dedit;

dedit.Pattern("%4n");

 

(You can also use the more traditional C-style formatters, like %4g or %3f, but the %n formatter is more flexible).

 

Note that Pattern is actually method of ConvertDouble, which is one of base classes for EditDouble.

 

Last edit by unodgs on 08/20/2006. Do you want to contribute?. T++