473,654 Members | 2,968 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Round float to X significant digits

Hi everybody, I've got a problem.

I'm trying to round a double to a particular number of significant
digits, in this case 5, but I can't figure out a way around getting
_exactly_ what I want instead of _about_ what I want. Taken down to just
the part relevant to my question, here's the code, the desired result,
and the actual result...

double somenumber = round(2453126.7 227083333 * 100000.0) / 100000.0;
desired: somenumber = 2453126.72271
actual: somenumber = 2453126.7227109 9999

I've implemented this exact function in a other languages (Ruby, PHP)
and never run into this problem, so there's got to be SOME kind of
solution. Before I start ripping through Ruby's interpreter's source to
find out how they managed this, I was hoping that somebody who reads
this board has come up with a solution already.

Unfortunately, I need this number in floating-point, or at least I'll
need to be able to reliably convert it to floating-point. Any ideas?
Jul 22 '05 #1
8 18765
David Corby wrote:
Hi everybody, I've got a problem.

I'm trying to round a double to a particular number of significant
digits, in this case 5, but I can't figure out a way around getting
_exactly_ what I want instead of _about_ what I want. Taken down to just
the part relevant to my question, here's the code, the desired result,
and the actual result...

double somenumber = round(2453126.7 227083333 * 100000.0) / 100000.0;
desired: somenumber = 2453126.72271
actual: somenumber = 2453126.7227109 9999

I've implemented this exact function in a other languages (Ruby, PHP)
and never run into this problem, so there's got to be SOME kind of
solution. Before I start ripping through Ruby's interpreter's source to
find out how they managed this, I was hoping that somebody who reads
this board has come up with a solution already.

Unfortunately, I need this number in floating-point, or at least I'll
need to be able to reliably convert it to floating-point. Any ideas?


Gaak!

actual: somenumber = 2453126.7227109 9999

should be

actual: somenumber = 2453126.7227099 999

Note the 5th decimal place is a 0 instead of 1. Sorry for the mistake there.
Jul 22 '05 #2
David Corby wrote:
David Corby wrote:
Hi everybody, I've got a problem.

I'm trying to round a double to a particular number of significant
digits, in this case 5, but I can't figure out a way around getting
_exactly_ what I want instead of _about_ what I want. Taken down to
just the part relevant to my question, here's the code, the desired
result, and the actual result...

double somenumber = round(2453126.7 227083333 * 100000.0) / 100000.0;

Not really sure if there is a function by name round in C++ .

#include <cmath>
#include <cstdio>
#include <cstdlib>

#define VAL 2453126.7227083 333
#define HALF 0.5
#define GREATER_EQUAL_H ALF(X) (X) >= HALF

double round(double val) {
long longval = (long)val;
if ( GREATER_EQUAL_H ALF(val - longval) ) {
return ceil(val);
} else {
return floor(val);
}
}

int main() {
double somenumber = round(VAL * 100000.0) / 100000.0;
printf("\nValue %lf rounded to %lf", VAL, somenumber);
return EXIT_SUCCESS;
}

Having said that, implementation of double and int data types at the
hardware level are drastically different. Thatz why, you can be sure
that, 5 == 5 always returns true ( assuming, int here ) whereas ( 5.1
== 5.1 ) does not guarantee.
When you talk about comparing double numbers, you always talk about
a small epsilon value (of your choice and tolerable limit, say 0.0000001).

HTH

--
Karthik
Humans please 'removeme_' for my real email.
Jul 22 '05 #3
In article <hT************ ********@twiste r.nyroc.rr.com> ,
David Corby <da**@lepertheo ry.net> wrote:
David Corby wrote:

I'm trying to round a double to a particular number of significant
digits, in this case 5, but I can't figure out a way around getting
_exactly_ what I want instead of _about_ what I want.

double somenumber = round(2453126.7 227083333 * 100000.0) / 100000.0;
desired: somenumber = 2453126.72271


actual: somenumber = 2453126.7227099 999


It's impossible in floating-point binary, because of the fundamental
nature of floating-point binary representation. See FAQ [29.16] at
<http://www.parashift.c om/c++-faq-lite/>.

--
Jon Bell <jt*******@pres by.edu> Presbyterian College
Dept. of Physics and Computer Science Clinton, South Carolina USA
Jul 22 '05 #4
Karthik wrote:
David Corby wrote:
David Corby wrote:
Hi everybody, I've got a problem.

I'm trying to round a double to a particular number of significant
digits, in this case 5, but I can't figure out a way around getting
_exactly_ what I want instead of _about_ what I want. Taken down to
just the part relevant to my question, here's the code, the desired
result, and the actual result...

double somenumber = round(2453126.7 227083333 * 100000.0) / 100000.0;


Not really sure if there is a function by name round in C++ .

#include <cmath>
#include <cstdio>
#include <cstdlib>

#define VAL 2453126.7227083 333
#define HALF 0.5
#define GREATER_EQUAL_H ALF(X) (X) >= HALF

double round(double val) {
long longval = (long)val;
if ( GREATER_EQUAL_H ALF(val - longval) ) {
return ceil(val);
} else {
return floor(val);
}
}

int main() {
double somenumber = round(VAL * 100000.0) / 100000.0;
printf("\nValue %lf rounded to %lf", VAL, somenumber);
return EXIT_SUCCESS;
}

Having said that, implementation of double and int data types at the
hardware level are drastically different. Thatz why, you can be sure
that, 5 == 5 always returns true ( assuming, int here ) whereas ( 5.1
== 5.1 ) does not guarantee.
When you talk about comparing double numbers, you always talk about a
small epsilon value (of your choice and tolerable limit, say 0.0000001).

HTH


Yes, it does help. Meh, I guess I'll just use a fixed decimal class.
Thanks for explaining the problem :)
Jul 22 '05 #5
David Corby <da**@lepertheo ry.net> wrote in message news:<hT******* *************@t wister.nyroc.rr .com>...
David Corby wrote:
Hi everybody, I've got a problem.

I'm trying to round a double to a particular number of significant
digits, in this case 5, but I can't figure out a way around getting
_exactly_ what I want instead of _about_ what I want. Taken down to just
the part relevant to my question, here's the code, the desired result,
and the actual result...

double somenumber = round(2453126.7 227083333 * 100000.0) / 100000.0;
desired: somenumber = 2453126.72271
actual: somenumber = 2453126.7227109 9999
[snip]


If you are only concerned about _printing_ the rounded number
(as opposed to round the number itsself)
you can use "classic C" printf():

#include <stdio.h>

int main() {
double x = 2453126.7227083 333;

printf ("x=%f, round to 2,3,4,5 digits:\n %.2f %.3f %.4f %.5f\n",
x, x, x, x, x);
}

This prints:
x=2453126.72270 8, round to 2,3,4,5 digits:
2453126.72 2453126.723 2453126.7227 2453126.72271

(There is, i am sure, also a C++ way to do this,
i am not familiar enough with <iomanip>'s setw(), setprecision() etc...
Maybe some C++ expert can post an example?)

HTH,
Bernhard Kick.
Jul 22 '05 #6
In comp.lang.c++
David Corby <da**@lepertheo ry.net> wrote:
Hi everybody, I've got a problem.

I'm trying to round a double to a particular number of significant
digits, in this case 5, but I can't figure out a way around getting
_exactly_ what I want instead of _about_ what I want. Taken down to just
the part relevant to my question, here's the code, the desired result,
and the actual result...

double somenumber = round(2453126.7 227083333 * 100000.0) / 100000.0;
desired: somenumber = 2453126.72271
actual: somenumber = 2453126.7227109 9999

I've implemented this exact function in a other languages (Ruby, PHP)
and never run into this problem, so there's got to be SOME kind of
solution. Before I start ripping through Ruby's interpreter's source to
find out how they managed this, I was hoping that somebody who reads
this board has come up with a solution already.

Unfortunatel y, I need this number in floating-point, or at least I'll
need to be able to reliably convert it to floating-point. Any ideas?


from Snippets:

/* round number n to d decimal points */

inline double fround(double n, unsigned d)
{
return floor(n * pow(10., d) + .5) / pow(10., d);
}

Jul 22 '05 #7
David Corby wrote:

Hi everybody, I've got a problem.

I'm trying to round a double to a particular number of significant
digits, in this case 5, but I can't figure out a way around getting
_exactly_ what I want instead of _about_ what I want. Taken down to just
the part relevant to my question, here's the code, the desired result,
and the actual result...

double somenumber = round(2453126.7 227083333 * 100000.0) / 100000.0;
desired: somenumber = 2453126.72271
actual: somenumber = 2453126.7227109 9999

I've implemented this exact function in a other languages (Ruby, PHP)
and never run into this problem, so there's got to be SOME kind of
solution. Before I start ripping through Ruby's interpreter's source to
find out how they managed this, I was hoping that somebody who reads
this board has come up with a solution already.

Unfortunately, I need this number in floating-point, or at least I'll
need to be able to reliably convert it to floating-point. Any ideas?


Do you need to *store* the result, or merely *display* the result?

Due to the way that floating point numbers are typically implemented, you
usually can't store an exact representation of all numbers, only approximations
as you have seen.
Jul 22 '05 #8
"Bernhard Kick" <be***********@ gmx.de> wrote in message
news:f2******** *************** ***@posting.goo gle.com...
double x = 2453126.7227083 333;

printf ("x=%f, round to 2,3,4,5 digits:\n %.2f %.3f %.4f %.5f\n",
x, x, x, x, x);
}

This prints:
x=2453126.72270 8, round to 2,3,4,5 digits:
2453126.72 2453126.723 2453126.7227 2453126.72271

(There is, i am sure, also a C++ way to do this,
i am not familiar enough with <iomanip>'s setw(), setprecision() etc...
Maybe some C++ expert can post an example?)


// std::cout << std::fixed; // optional
std::cout << std::precicsion (2) << x; // print 2453126.72
As for the getting the exact number in memory, it is generally impossible,
because 2.00008 may be represented internally in binary format, and will
display in decimal as 2.0000799999999 99999... Nevertheless, you can write
a general round function like

return std::floor(x*10 000.0+0.5)/10000

But the use of division and floor may make the function slow, and better
solutions may be available.
Jul 22 '05 #9

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

Similar topics

11
2520
by: Russell E. Owen | last post by:
I realize this probably a stupid question, but...is it safe to round to the nearest integer by using int(round(val))? I suspect it is fine, but wanted to be sure that weird floating point representation on some platform might make it unsafe there (i.e. get the wrong value due to the floating point value being an approximation) and if so, is there a Better Way). -- Russell
5
12611
by: Peter Scheurer | last post by:
Hi, we found some strange behavior when operating with floats and round(). The following simplified statement reproduces the problem. select 6.56 - round(convert(float, 6.56), 2) from sysusers where name = 'public'; =========== -8.88178419
2
9479
by: Andy | last post by:
Could anyone tell me how to round off a number to certain significant figures using C++? For example, how to round off a number 12567 to 13000 (2 significant figures)?
9
16793
by: kdlittle88 | last post by:
Does anyone have any sample code on how to round off a float to x digits? say for example rounding 3.1415 to 3.1? Any help would be appreciated. I am learning C++ and have not found this info on the net (though it might be out there) tiny k
12
8235
by: Nobody | last post by:
I'm trying to understand why this program... #include <stdio.h> #include <float.h> int main(void) { int i = 123456789 ; int j = 987654321 ;
4
1447
by: RD | last post by:
The statements The value passed to Amount by the function call is 111111111111111.98 and is a double then we 4execute the following code snippet Dim New_amt as string New_amt = Format(amount, "000000000000000.00")
4
9464
by: Phil Mc | last post by:
OK this should be bread and butter, easy to do, but I seem to be going around in circles and not getting any answer to achieving this simple task. I have numbers in string format (they are coming in from an excel sheet): Examples. 45,666.0041 5664456.12 -5465.25568 ETC
60
7194
by: Erick-> | last post by:
hi all... I've readed some lines about the difference between float and double data types... but, in the real world, which is the best? when should we use float or double?? thanks Erick
7
4777
by: ma740988 | last post by:
Consider the equation (flight dynamics stuff): Yaw (Degrees) = Azimuth Angle(Radians) * 180 (Degrees) / 3.1415926535897932384626433832795 (Radians) There's a valid reason to use single precision floating point types. The number of decimal digits guaranteed to be correct on my implementation is 6. (i.e numeric_limits < float >::digits10 = 6 ) If I'm reading the IEEE standard, I'd could paraphrase the issue
0
8372
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
8285
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8814
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...
1
8475
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
7304
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...
1
6160
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5621
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
4149
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...
1
1915
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.