rounding to the nearest nth digits

G

Gary Wessle

Hi

I googled, RTM, checked round, floor, ceil, setprecision for no avail.
I have a vector<double> which 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
 
M

mohammad.nabil.h

Gary said:
Hi

I googled, RTM, checked round, floor, ceil, setprecision for no avail.
I have a vector<double> which 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);
 
I

Ivan Vecerina

: I googled, RTM, checked round, floor, ceil, setprecision for no avail.
: I have a vector<double> which 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 = floor( v*mul + 0.5 ) / mul;

hth -Ivan
 
H

Howard

Ivan Vecerina said:
: I googled, RTM, checked round, floor, ceil, setprecision for no avail.
: I have a vector<double> which 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 = floor( v*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
 
V

Victor Bazarov

Gary said:
I googled, RTM, checked round, floor, ceil, setprecision for no avail.
I have a vector<double> which 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
 
G

Gary Wessle

Gary Wessle said:
Hi

I googled, RTM, checked round, floor, ceil, setprecision for no avail.
I have a vector<double> which 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
 
L

Larry I Smith

Gary said:
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.

Use at your own risk...

#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 */

}
 
G

Gary Wessle

Victor Bazarov said:
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.
 
L

Larry I Smith

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

Use at your own risk...

#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
 
V

Victor Bazarov

Gary said:
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.

Read about i/o manipulators, especially 'setprecision'.

V
 
?

=?iso-8859-1?q?Kirit_S=E6lensminde?=

Gary said:
Hi

I googled, RTM, checked round, floor, ceil, setprecision for no avail.
I have a vector<double> which 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
 
M

Marcus Kwok

Gary Wessle said:
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

You want to add std::fixed to your output statement.


#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

*/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top