473,776 Members | 1,645 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Rounding a floating point number

Hi

"How can I round a number to x decimal places" ?

This question keeps appearing. I would propose the following
solution

#include <float.h>
#include <math.h>

double roundto(double x, int digits)
{
int sgn=1;

if (x == 0)
return 0;
if (digits DBL_DIG)
digits = DBL_DIG;
else if (digits < 1)
digits = 1;

if(x < 0.0) {
sgn = -sgn;
x = -x;
}
double p = floorl(log10l(x ));
p--;
p = digits-p;
double pow10 = pow(10.0, p);
return sgn*floor(x*pow 10+0.5)/pow10;
}

long double roundtol(long double x, int digits)
{
int sgn=1;

if (x == 0)
return 0;
if (digits LDBL_DIG)
digits = LDBL_DIG;
else if (digits < 1)
digits = 1;

if(x < 0.0) {
sgn = -sgn;
x = -x;
}
long double p = floorl(log10l(x ));
p--;
p = digits-p;
long double pow10 = powl(10.0, p);
return sgn*floorl(x*po w10+0.5)/pow10;
}
#include <stdio.h>
int main(void)
{
double d = 1.7888889988996 678;
long double ld = 1.7888889988996 678998877L;

for (int i = 0; i<=DBL_DIG;i++ ) {
printf("i=%d: %.15g\n",i,roun dto(d,i));
}
printf("\n 1.7888889988996 678\n");
for (int i = 0; i<=LDBL_DIG;i++ ) {
printf("i=%d: %.18Lg\n",i,rou ndtol(ld,i));
}
printf("\n 1.7888889988996 678998877L\n");
return 0;
}

--------------------------------------------------------------------
I would propose it to add it to the FAQ.
--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
Feb 25 '08
20 5014
On Feb 25, 2:18*am, jacob navia <ja...@nospam.c omwrote:
Hi

"How can I round a number to x decimal places" ?

This question keeps appearing. I would propose the following
solution

#include <float.h>
#include <math.h>

double roundto(double x, int digits)
{
* * * * int sgn=1;

* * * * if (x == 0)
* * * * * * * * return 0;
* * * * if (digits DBL_DIG)
* * * * * * * * digits = DBL_DIG;
* * * * else if (digits < 1)
* * * * * * * * digits = 1;

* * * * if(x < 0.0) {
* * * * * * * * sgn = -sgn;
* * * * * * * * x = -x;
* * * * }
* * * * double p = floorl(log10l(x ));
* * * * p--;
* * * * p = digits-p;
* * * * double pow10 = pow(10.0, p);
* * * * return sgn*floor(x*pow 10+0.5)/pow10;

}

long double roundtol(long double x, int digits)
{
* * * * int sgn=1;

* * * * if (x == 0)
* * * * * * * * return 0;
* * * * if (digits LDBL_DIG)
* * * * * * * * digits = LDBL_DIG;
* * * * else if (digits < 1)
* * * * * * * * digits = 1;

* * * * if(x < 0.0) {
* * * * * * * * sgn = -sgn;
* * * * * * * * x = -x;
* * * * }
* * * * long double p = floorl(log10l(x ));
* * * * p--;
* * * * p = digits-p;
* * * * long double pow10 = powl(10.0, p);
* * * * return sgn*floorl(x*po w10+0.5)/pow10;}

#include <stdio.h>
int main(void)
{
* * * * double d = 1.7888889988996 678;
* * * * long double ld = 1.7888889988996 678998877L;

* * * * for (int i = 0; i<=DBL_DIG;i++ ) {
* * * * * * * * printf("i=%d: %.15g\n",i,roun dto(d,i));
* * * * }
* * * * printf("\n * * *1.788888998899 6678\n");
* * * * for (int i = 0; i<=LDBL_DIG;i++ ) {
* * * * * * * * printf("i=%d: %.18Lg\n",i,rou ndtol(ld,i));
* * * * }
* * * * printf("\n * * *1.788888998899 6678998877L\n") ;
* * * * return 0;

}

--------------------------------------------------------------------
I would propose it to add it to the FAQ.
The snippets solution, tweaked a little bit:

#include <math.h>
/* round number n to d decimal points */
long double roundl(const long double n, const unsigned d)
{
long double p = powl(10., d);
return floorl(n * p + .5) / p;
}

/* round number n to d decimal points */
double roundd(const double n, const unsigned d)
{
return (double) roundl((long double) n, d);
}

/* round number n to d decimal points */
double roundf(const float n, const unsigned d)
{
return (float) roundl((long double) n, d);
}
#ifdef UNIT_TEST
#include <stdio.h>
#include <stdlib.h>
#include <float.h>
int main(void)
{
long double pi = 3.1415926535897 932384626433832 795;
long double npi = -pi;
unsigned digits;
for (digits = 0; digits <= LDBL_DIG; digits++) {
printf("Roundin g by printf gives: %20.*f\n",
digits, pi);
printf("Roundin g approximation by function gives: %20.*f\n",
LDBL_DIG, roundl(pi, digits));
printf("Roundin g approximation by function gives: %20.*f\n",
DBL_DIG, roundd(pi, digits));
printf("Roundin g approximation by function gives: %20.*f\n\n",
FLT_DIG, roundf(pi, digits));
}
for (digits = 0; digits <= LDBL_DIG; digits++) {
printf("Roundin g by printf gives: %20.*f\n",
digits, npi);
printf("Roundin g approximation by function gives: %20.*f\n",
LDBL_DIG, roundl(npi, digits));
printf("Roundin g approximation by function gives: %20.*f\n",
DBL_DIG, roundd(npi, digits));
printf("Roundin g approximation by function gives: %20.*f\n\n",
FLT_DIG, roundf(npi, digits));
}
return 0;
}
#endif
/*
Rounding by printf gives: 3
Rounding approximation by function gives: 3.0000000000000 00
Rounding approximation by function gives: 3.0000000000000 00
Rounding approximation by function gives: 3.000000

Rounding by printf gives: 3.1
Rounding approximation by function gives: 3.1000000000000 00
Rounding approximation by function gives: 3.1000000000000 00
Rounding approximation by function gives: 3.100000

Rounding by printf gives: 3.14
Rounding approximation by function gives: 3.1400000000000 00
Rounding approximation by function gives: 3.1400000000000 00
Rounding approximation by function gives: 3.140000

Rounding by printf gives: 3.142
Rounding approximation by function gives: 3.1420000000000 00
Rounding approximation by function gives: 3.1420000000000 00
Rounding approximation by function gives: 3.142000

Rounding by printf gives: 3.1416
Rounding approximation by function gives: 3.1416000000000 00
Rounding approximation by function gives: 3.1416000000000 00
Rounding approximation by function gives: 3.141600

Rounding by printf gives: 3.14159
Rounding approximation by function gives: 3.1415900000000 00
Rounding approximation by function gives: 3.1415900000000 00
Rounding approximation by function gives: 3.141590

Rounding by printf gives: 3.141593
Rounding approximation by function gives: 3.1415930000000 00
Rounding approximation by function gives: 3.1415930000000 00
Rounding approximation by function gives: 3.141593

Rounding by printf gives: 3.1415927
Rounding approximation by function gives: 3.1415927000000 00
Rounding approximation by function gives: 3.1415927000000 00
Rounding approximation by function gives: 3.141593

Rounding by printf gives: 3.14159265
Rounding approximation by function gives: 3.1415926500000 00
Rounding approximation by function gives: 3.1415926500000 00
Rounding approximation by function gives: 3.141593

Rounding by printf gives: 3.141592654
Rounding approximation by function gives: 3.1415926540000 00
Rounding approximation by function gives: 3.1415926540000 00
Rounding approximation by function gives: 3.141593

Rounding by printf gives: 3.1415926536
Rounding approximation by function gives: 3.1415926536000 00
Rounding approximation by function gives: 3.1415926536000 00
Rounding approximation by function gives: 3.141593

Rounding by printf gives: 3.14159265359
Rounding approximation by function gives: 3.1415926535900 00
Rounding approximation by function gives: 3.1415926535900 00
Rounding approximation by function gives: 3.141593

Rounding by printf gives: 3.141592653590
Rounding approximation by function gives: 3.1415926535900 00
Rounding approximation by function gives: 3.1415926535900 00
Rounding approximation by function gives: 3.141593

Rounding by printf gives: 3.1415926535898
Rounding approximation by function gives: 3.1415926535898 00
Rounding approximation by function gives: 3.1415926535898 00
Rounding approximation by function gives: 3.141593

Rounding by printf gives: 3.1415926535897 9
Rounding approximation by function gives: 3.1415926535897 90
Rounding approximation by function gives: 3.1415926535897 90
Rounding approximation by function gives: 3.141593

Rounding by printf gives: 3.1415926535897 93
Rounding approximation by function gives: 3.1415926535897 93
Rounding approximation by function gives: 3.1415926535897 93
Rounding approximation by function gives: 3.141593

Rounding by printf gives: -3
Rounding approximation by function gives: -3.0000000000000 00
Rounding approximation by function gives: -3.0000000000000 00
Rounding approximation by function gives: -3.000000

Rounding by printf gives: -3.1
Rounding approximation by function gives: -3.1000000000000 00
Rounding approximation by function gives: -3.1000000000000 00
Rounding approximation by function gives: -3.100000

Rounding by printf gives: -3.14
Rounding approximation by function gives: -3.1400000000000 00
Rounding approximation by function gives: -3.1400000000000 00
Rounding approximation by function gives: -3.140000

Rounding by printf gives: -3.142
Rounding approximation by function gives: -3.1420000000000 00
Rounding approximation by function gives: -3.1420000000000 00
Rounding approximation by function gives: -3.142000

Rounding by printf gives: -3.1416
Rounding approximation by function gives: -3.1416000000000 00
Rounding approximation by function gives: -3.1416000000000 00
Rounding approximation by function gives: -3.141600

Rounding by printf gives: -3.14159
Rounding approximation by function gives: -3.1415900000000 00
Rounding approximation by function gives: -3.1415900000000 00
Rounding approximation by function gives: -3.141590

Rounding by printf gives: -3.141593
Rounding approximation by function gives: -3.1415930000000 00
Rounding approximation by function gives: -3.1415930000000 00
Rounding approximation by function gives: -3.141593

Rounding by printf gives: -3.1415927
Rounding approximation by function gives: -3.1415927000000 00
Rounding approximation by function gives: -3.1415927000000 00
Rounding approximation by function gives: -3.141593

Rounding by printf gives: -3.14159265
Rounding approximation by function gives: -3.1415926500000 00
Rounding approximation by function gives: -3.1415926500000 00
Rounding approximation by function gives: -3.141593

Rounding by printf gives: -3.141592654
Rounding approximation by function gives: -3.1415926540000 00
Rounding approximation by function gives: -3.1415926540000 00
Rounding approximation by function gives: -3.141593

Rounding by printf gives: -3.1415926536
Rounding approximation by function gives: -3.1415926536000 00
Rounding approximation by function gives: -3.1415926536000 00
Rounding approximation by function gives: -3.141593

Rounding by printf gives: -3.14159265359
Rounding approximation by function gives: -3.1415926535900 00
Rounding approximation by function gives: -3.1415926535900 00
Rounding approximation by function gives: -3.141593

Rounding by printf gives: -3.141592653590
Rounding approximation by function gives: -3.1415926535900 00
Rounding approximation by function gives: -3.1415926535900 00
Rounding approximation by function gives: -3.141593

Rounding by printf gives: -3.1415926535898
Rounding approximation by function gives: -3.1415926535898 00
Rounding approximation by function gives: -3.1415926535898 00
Rounding approximation by function gives: -3.141593

Rounding by printf gives: -3.1415926535897 9
Rounding approximation by function gives: -3.1415926535897 90
Rounding approximation by function gives: -3.1415926535897 90
Rounding approximation by function gives: -3.141593

Rounding by printf gives: -3.1415926535897 93
Rounding approximation by function gives: -3.1415926535897 93
Rounding approximation by function gives: -3.1415926535897 93
Rounding approximation by function gives: -3.141593
*/
Feb 25 '08 #11
jacob navia wrote:
>
"How can I round a number to x decimal places" ?

This question keeps appearing. I would propose the following
.... snip 75 or so lines ...

Why all this gyration? I found the following in the c standard:

7.12.9.6 The round functions
Synopsis
[#1]
#include <math.h>
double round(double x);
float roundf(float x);
long double roundl(long double x);

Description

[#2] The round functions round their argument to the nearest
integer value in floating-point format, rounding halfway
cases away from zero, regardless of the current rounding
direction.

Returns

[#3] The round functions return the rounded integer value.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home .att.net>
Try the download section.

--
Posted via a free Usenet account from http://www.teranews.com

Feb 25 '08 #12
CBFalconer <cb********@yah oo.comwrites:
jacob navia wrote:
>>
"How can I round a number to x decimal places" ?

This question keeps appearing. I would propose the following
... snip 75 or so lines ...

Why all this gyration? I found the following in the c standard:

7.12.9.6 The round functions
Those functions are new in C99.
--
char a[]="\n .CJacehknorstu" ;int putchar(int);in t main(void){unsi gned long b[]
={0x67dffdff,0x 9aa9aa6a,0xa77f fda9,0x7da6aa6a ,0xa67f6aaa,0xa a9aa9f6,0x11f6} ,*p
=b,i=24;for(;p+ =!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
2:{i++;if(i)bre ak;else default:continu e;if(0)case 1:putchar(a[i&15]);break;}}}
Feb 26 '08 #13
On Feb 25, 4:29*pm, Ben Pfaff <b...@cs.stanfo rd.eduwrote:
CBFalconer <cbfalco...@yah oo.comwrites:
jacob navia wrote:
"How can I round a number to x decimal places" ?
This question keeps appearing. I would propose the following
... snip 75 or so lines ...
Why all this gyration? *I found the following in the c standard:
* 7.12.9.6 *The round functions

Those functions are new in C99.
And they don't round to x decimal places, unless x happens to be
zero. (Admittedly, you could manually scale it.)

Feb 26 '08 #14
Ben Pfaff <bl*@cs.stanfor d.eduwrites:
CBFalconer <cb********@yah oo.comwrites:
>jacob navia wrote:
>>"How can I round a number to x decimal places" ?

This question keeps appearing. I would propose the following
... snip 75 or so lines ...

Why all this gyration? I found the following in the c standard:

7.12.9.6 The round functions

Those functions are new in C99.
So are floorl and log10l, which jacob's code uses; it also mixes
declarations and statements within a block. An implementation that
can handle jacob's code should provide the round functions.

--
Keith Thompson (The_Other_Keit h) <ks***@mib.or g>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Feb 26 '08 #15
On Feb 25, 10:15*pm, Keith Thompson <ks...@mib.orgw rote:
Ben Pfaff <b...@cs.stanfo rd.eduwrites:
CBFalconer <cbfalco...@yah oo.comwrites:
jacob navia wrote:
"How can I round a number to x decimal places" ?
>This question keeps appearing. I would propose the following
... snip 75 or so lines ...
Why all this gyration? *I found the following in the c standard:
* 7.12.9.6 *The round functions
Those functions are new in C99.

So are floorl and log10l, which jacob's code uses; it also mixes
declarations and statements within a block. *An implementation that
can handle jacob's code should provide the round functions.
You will still have to multiply and divide by powers of 10 and use
floor() to achieve the same thing because the C99 round() functions
round to nearest integer. They do not round to nearest k decimal
places.
Feb 26 '08 #16
user923005 wrote:
>
.... snip float rounding discussion ...
>
You will still have to multiply and divide by powers of 10 and use
floor() to achieve the same thing because the C99 round() functions
round to nearest integer. They do not round to nearest k decimal
places.
Are you claiming that such multiplication and division by 10 is too
complex for the average reader of c.l.c? :-)

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home .att.net>
Try the download section.

--
Posted via a free Usenet account from http://www.teranews.com

Feb 27 '08 #17
On Feb 26, 2:24*pm, CBFalconer <cbfalco...@yah oo.comwrote:
user923005 wrote:

... snip float rounding discussion ...
You will still have to multiply and divide by powers of 10 and use
floor() to achieve the same thing because the C99 round() functions
round to nearest integer. *They do not round to nearest k decimal
places.

Are you claiming that such multiplication and division by 10 is too
complex for the average reader of c.l.c? *:-)
No, but I am claiming that using the C99 functions to round to N
digits will take twice as much work as a function that does it
directly, since the multiplication and division by a power of ten and
the floor function are all that is necessary in either case. And so
while you can round to N digits using the C99 rounding functions, it
really does not make a lot of sense to do it that way.
Feb 27 '08 #18
user923005 wrote:
CBFalconer <cbfalco...@yah oo.comwrote:
>user923005 wrote:

... snip float rounding discussion ...
>>You will still have to multiply and divide by powers of 10 and
use floor() to achieve the same thing because the C99 round()
functions round to nearest integer. They do not round to
nearest k decimal places.

Are you claiming that such multiplication and division by 10 is
too complex for the average reader of c.l.c? :-)

No, but I am claiming that using the C99 functions to round to N
digits will take twice as much work as a function that does it
directly, since the multiplication and division by a power of
ten and the floor function are all that is necessary in either
case. And so while you can round to N digits using the C99
rounding functions, it really does not make a lot of sense to do
it that way.
Let me also point out that such rounding is rarely needed. Most of
the time maintaining the original alleged precision and rounding
only the output, via printf, is needed.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home .att.net>
Try the download section.

--
Posted via a free Usenet account from http://www.teranews.com

Feb 27 '08 #19
On Feb 27, 8:10*am, CBFalconer <cbfalco...@yah oo.comwrote:
user923005 wrote:
CBFalconer <cbfalco...@yah oo.comwrote:
user923005 wrote:
... snip float rounding discussion ...
>You will still have to multiply and divide by powers of 10 and
use floor() to achieve the same thing because the C99 round()
functions round to nearest integer. *They do not round to
nearest k decimal places.
Are you claiming that such multiplication and division by 10 is
too complex for the average reader of c.l.c? *:-)
No, but I am claiming that using the C99 functions to round to N
digits will take twice as much work as a function that does it
directly, since the multiplication and division by a power of
ten and the floor function are all that is necessary in either
case. *And so while you can round to N digits using the C99
rounding functions, it really does not make a lot of sense to do
it that way.

Let me also point out that such rounding is rarely needed. *Most of
the time maintaining the original alleged precision and rounding
only the output, via printf, is needed.
I would go one step further:
It's better than rounding the original data.
But sometimes people want to do it anyway.
Feb 28 '08 #20

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

20
11731
by: Raoul Watson | last post by:
By any chance, anyone got a rounding routine that does a work around the VB "round" bug? I still find it amazing that a company as large as Microsoft would put out a math package that is so problematic.
6
9021
by: Curley Q. | last post by:
Is there a std lib rounding function that will round a real to a given number of decimal places? Something like: double round_it(double number, int decimal_digits) pass 34.5678, 3 to it and it returns 34.568
13
15627
by: kennethlou | last post by:
Hi, If in C a variable appears like X=10.000000, I can round it to zero decimal places. ie X=10? I then have to save the number into a variable. The method appears below: ************************************** >printf("Round % .f \n", 10.0000000);
29
3191
by: Marco | last post by:
Hello, I have : float f = 36.09999999; When I do : char cf; sprintf(cf,"%0.03lf", f); I get : 36.100
15
8064
by: Mukesh_Singh_Nick | last post by:
Why does floating point have a rounding error? How to work around it? For example, the following: flaot f = 1234.12345678F; printf("%2f\n", f) //prints 1234.123413 and
206
13311
by: md | last post by:
Hi Does any body know, how to round a double value with a specific number of digits after the decimal points? A function like this: RoundMyDouble (double &value, short numberOfPrecisions) It then updates the value with numberOfPrecisions after the decimal
0
9628
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10289
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10120
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
8952
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6722
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5367
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5493
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4031
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3622
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.