471,831 Members | 1,141 Online

# rounding to the nearest nth digits

Hi

I googled, RTM, checked round, floor, ceil, setprecision for no avail.
I have a vector<doublewhich I need to round its elements to the nth
digit so that if n is 2 then
1.135 would be 1.14
0.9955 would be 1.00

thanks

Aug 8 '06 #1
11 8083

Gary Wessle wrote:
Hi

I googled, RTM, checked round, floor, ceil, setprecision for no avail.
I have a vector<doublewhich I need to round its elements to the nth
digit so that if n is 2 then
1.135 would be 1.14
0.9955 would be 1.00

thanks
I think if x = 1.135 and you want to round it to the 2nd (n=2) digit
(so it'll be 1.14) do this
x=round(x*(pow(10,n))/pow(10,n);

Aug 8 '06 #2
"Gary Wessle" <ph****@yahoo.comwrote in message
news:87************@yahoo.com...
: I googled, RTM, checked round, floor, ceil, setprecision for no avail.
: I have a vector<doublewhich I need to round its elements to the nth
: digit so that if n is 2 then
: 1.135 would be 1.14
: 0.9955 would be 1.00
For example:
double mul = pow(10,n);
for( ... i = .... )
v[i] = floor( v[i]*mul + 0.5 ) / mul;

hth -Ivan
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form
Aug 8 '06 #3

"Ivan Vecerina" <IN*****************@ivan.vecerina.comwrote in message
news:88**************************@news.hispeed.ch. ..
"Gary Wessle" <ph****@yahoo.comwrote in message
news:87************@yahoo.com...
: I googled, RTM, checked round, floor, ceil, setprecision for no avail.
: I have a vector<doublewhich I need to round its elements to the nth
: digit so that if n is 2 then
: 1.135 would be 1.14
: 0.9955 would be 1.00
For example:
double mul = pow(10,n);
for( ... i = .... )
v[i] = floor( v[i]*mul + 0.5 ) / mul;
There's no guarantee that that will result in the value desired. Remember,
floating-point values are binary representations, and can only be exactly
represented for a small subset of specific values. Just like there's no way
to represent 1/3 exactly using decimals (it's .3333333... forever), there is
no way to represent many fractions using binary. So making this type of
calculation, where n can be anything, may result in values near to what you
want, but not exact.

The question is, where does the rounding need to occur? If it's just for
output, then the correct thing to do would probably be to format the output,
not to modify the stored value.

If you're talking about currency (such as dollars and cents) or some other
fixed-point system, then you might want to simply scale everything upwards
as needed. For example, instead of storing 1.135 as 1.14, you could scale
it up to 113.5, then round that to the integer 114. Then you can stick the
decimal where you want it when displaying or printing out the value.

If you've got a more complex (or generic) situation, then perhaps you could
explain it more fully and someone could suggest a solution for your
particular needs.

-Howard

Aug 8 '06 #4
Gary Wessle wrote:
I googled, RTM, checked round, floor, ceil, setprecision for no avail.
I have a vector<doublewhich I need to round its elements to the nth
digit so that if n is 2 then
1.135 would be 1.14
0.9955 would be 1.00
What for? What problem are you trying to solve by rounding?

V
--
Aug 8 '06 #5
Gary Wessle <ph****@yahoo.comwrites:
Hi

I googled, RTM, checked round, floor, ceil, setprecision for no avail.
I have a vector<doublewhich I need to round its elements to the nth
digit so that if n is 2 then
1.135 would be 1.14
0.9955 would be 1.00

thanks
double x = 1.123;
double y = 10.215;
cout << setprecision(4) << x << " "
<< setprecision(4) << y << endl;

cout << setprecision(2) << x << " "
<< setprecision(2) << y << endl;

**************** outputs ****************
1.123 10.21
1.1 10

**************** desired ****************
1.1230 10.2150
1.12 10.22
Aug 8 '06 #6
Gary Wessle wrote:
Gary Wessle <ph****@yahoo.comwrites:
>Hi

I googled, RTM, checked round, floor, ceil, setprecision for no avail.
I have a vector<doublewhich I need to round its elements to the nth
digit so that if n is 2 then
1.135 would be 1.14
0.9955 would be 1.00

thanks

double x = 1.123;
double y = 10.215;
cout << setprecision(4) << x << " "
<< setprecision(4) << y << endl;

cout << setprecision(2) << x << " "
<< setprecision(2) << y << endl;

**************** outputs ****************
1.123 10.21
1.1 10

**************** desired ****************
1.1230 10.2150
1.12 10.22
This code dates from 1991. It was used to display
financial data on reports.

#include <math.h>

/* round then trunc z at d decimal digits
* z; nbr to round
* d; dec digits to round/trunc to: 0 - 14
*/
double FixDec(double z, int d)
{
double m, f;

if(z == 0.0) return(z);

if(d < 0) d = 0;
if(d 14) d = 14; /* IEEE doubles max precision minus 1 */
/* comments show what would happen if z = 1234.5678 & d = 2 */
m = pow(10.0, (double)d); /* m: = 100.0 */
z *= m; /* z: 1234.5678 -123456.78 */
f = modf(z, &z); /* z: 123456.78 -123456.0 & f = 0.78 */
f *= 10.0; /* f: 0.78 -7.8 */
modf(f, &f); /* f: 7.8 -7.0 */
if((int)f 4)
z += 1.0; /* z: 123456.0 -123457.0 */

return(z / m); /* 123457.0 / 100.0 = 1234.57 */

}
Aug 8 '06 #7
"Victor Bazarov" <v.********@comAcast.netwrites:
Gary Wessle wrote:
>I googled, RTM, checked round, floor, ceil, setprecision for no avail.
I have a vector<doublewhich I need to round its elements to the nth
digit so that if n is 2 then
1.135 would be 1.14
0.9955 would be 1.00

What for? What problem are you trying to solve by rounding?
so that instead of printing 1.123, it prints 1.12 and instead of
10.123 it prints 10.12, pretty printing is what I am after.
Aug 8 '06 #8
Larry I Smith wrote:
Gary Wessle wrote:
>Gary Wessle <ph****@yahoo.comwrites:
>>Hi

I googled, RTM, checked round, floor, ceil, setprecision for no avail.
I have a vector<doublewhich I need to round its elements to the nth
digit so that if n is 2 then
1.135 would be 1.14
0.9955 would be 1.00

thanks
double x = 1.123;
double y = 10.215;
cout << setprecision(4) << x << " "
<< setprecision(4) << y << endl;

cout << setprecision(2) << x << " "
<< setprecision(2) << y << endl;

**************** outputs ****************
1.123 10.21
1.1 10

**************** desired ****************
1.1230 10.2150
1.12 10.22

This code dates from 1991. It was used to display
financial data on reports.

#include <math.h>

/* round then trunc z at d decimal digits
* z; nbr to round
* d; dec digits to round/trunc to: 0 - 14
*/
double FixDec(double z, int d)
{
double m, f;

if(z == 0.0) return(z);

if(d < 0) d = 0;
if(d 14) d = 14; /* IEEE doubles max precision minus 1 */
/* comments show what would happen if z = 1234.5678 & d = 2 */
m = pow(10.0, (double)d); /* m: = 100.0 */
z *= m; /* z: 1234.5678 -123456.78 */
f = modf(z, &z); /* z: 123456.78 -123456.0 & f = 0.78 */
f *= 10.0; /* f: 0.78 -7.8 */
modf(f, &f); /* f: 7.8 -7.0 */
if((int)f 4)
z += 1.0; /* z: 123456.0 -123457.0 */

return(z / m); /* 123457.0 / 100.0 = 1234.57 */

}
I must note that the return value from FixDec() was then used in
an fprintf() call using a format string (something like "10.2lf").

Larry
Aug 8 '06 #9
Gary Wessle wrote:
"Victor Bazarov" <v.********@comAcast.netwrites:
>Gary Wessle wrote:
>>I googled, RTM, checked round, floor, ceil, setprecision for no
avail. I have a vector<doublewhich I need to round its elements
to the nth digit so that if n is 2 then
1.135 would be 1.14
0.9955 would be 1.00

What for? What problem are you trying to solve by rounding?

so that instead of printing 1.123, it prints 1.12 and instead of
10.123 it prints 10.12, pretty printing is what I am after.

V
--
Aug 9 '06 #10

Gary Wessle wrote:
Hi

I googled, RTM, checked round, floor, ceil, setprecision for no avail.
I have a vector<doublewhich I need to round its elements to the nth
digit so that if n is 2 then
1.135 would be 1.14
0.9955 would be 1.00

thanks
This is a right royal pain in the wossname. It seems that everybody
gets so carried away with significant figures and thinks there is no
good reason to use number of decimal places.

For your use in currencies though using reals is a very bad idea. You
should be using an integer type multiplied by some value (100 or 1000)
depending on the currency and the accuracy required.

Having said that though if you have old code that's already using
floats to store money I just hope it's for reporting purposes...

Here is what I came up with (f is a real, set dp to the number of
places):

int mag = int( std::log10( f ) );
if ( dp + mag < 1 )
ss << std::setprecision( dp + 1 ) << 0.0;
else
ss << std::setprecision( dp + mag + 1 ) << f;
I'm sure this has all sorts of interesting behaviour for extreme values
and numbers of places. I'm also not sure what happens if dp is set to a
negative value - haven't needed it and haven't thought it through.

In case people are wondering why on earth you'd want to do this sort of
thing consider lat/lon positions. Your GPS doesn't suddenly become more
accurate as you near the meridian.

0.123456W is the same accuracy as 100.123456W. If you output 0.123456
and then 100.124 then you're doing something very wrong. Reals are the
natural representation to use to store these numbers too.
K

Aug 9 '06 #11
Gary Wessle <ph****@yahoo.comwrote:
Gary Wessle <ph****@yahoo.comwrites:
>I googled, RTM, checked round, floor, ceil, setprecision for no avail.
I have a vector<doublewhich I need to round its elements to the nth
digit so that if n is 2 then
1.135 would be 1.14
0.9955 would be 1.00

thanks

double x = 1.123;
double y = 10.215;
cout << setprecision(4) << x << " "
<< setprecision(4) << y << endl;

cout << setprecision(2) << x << " "
<< setprecision(2) << y << endl;

**************** outputs ****************
1.123 10.21
1.1 10

**************** desired ****************
1.1230 10.2150
1.12 10.22
#include <iostream>
#include <iomanip>

int main()
{
double x = 1.123;
double y = 10.215;
std::cout << std::fixed << std::setprecision(4) << x << " "
<< std::setprecision(4) << y << '\n';

std::cout << std::setprecision(2) << x << " "
<< std::setprecision(2) << y << '\n';
}

/*

Output:
1.1230 10.2150
1.12 10.22

*/

--
Marcus Kwok
Replace 'invalid' with 'net' to reply
Aug 9 '06 #12

### This discussion thread is closed

Replies have been disabled for this discussion.