473,395 Members | 1,905 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Rounding by prayer?

I'm surprised I haven't hit this situation till now, but I don't believe
I've had to deal with it before. I have a function that sets the
components of a point class (QPoint from Qt). It takes integer arguments
for the components. I am calculating the values using transcendental
functions sin and cos which return floating point type values. (The
compiler claims they are double though I expected float in, float out.) I
guess I have some choices as to whether I pass the floating point values
and let the conversion take place automagically, or convert first and then
pass the resulting integers. How is such a situation typically handled in
C++?

So far as I know there is no explicit round() function native to C++ that
will round a float or double to an int or size_t. Is this correct?
Here's a code snippet that has the actual invocation in it:
namespace drawings
{
static float pi = acos(-1.0f); // not sure if static is right here.
StarFactory::StarFactory():
edgeLength(100.0f)
{
size_t n = StarFactory::NUMBER_OF_POINTS;
this->pointArrayPtr = new QPointArray(n);
float dTheta = 2.0f/float(n) * pi;
float l = this->edgeLength;
for(size_t i = 0; i < n; i++)
{
float theta = float(i) * dTheta;
/*The following line is where the conversion happens*/
this->pointArrayPtr->setPoint(i, l * cos(theta), l * sin(theta));
}
}

StarFactory::~StarFactory()
{
/// @todo destroy me
}
}
;

--
STH
Hatton's Law: "There is only One inviolable Law"
KDevelop: http://www.kdevelop.org SuSE: http://www.suse.com
Mozilla: http://www.mozilla.org
Jul 22 '05 #1
7 4083
On Sat, 03 Jul 2004 04:18:37 -0400, Steven T. Hatton
<su******@setidava.kushan.aa> wrote:
I'm surprised I haven't hit this situation till now, but I don't believe
I've had to deal with it before. I have a function that sets the
components of a point class (QPoint from Qt). It takes integer arguments
for the components. I am calculating the values using transcendental
functions sin and cos which return floating point type values. (The
compiler claims they are double though I expected float in, float out.)
You should normally use doubles. I can't see any reason not to in your
code. Obviously doubles have more precision and greater range, but
(apparently) on floating point hardware they are as fast as if, not
faster, than floats. So the only reason to use floats is to save space,
which isn't the case for your code.
I
guess I have some choices as to whether I pass the floating point values
and let the conversion take place automagically, or convert first and
then
pass the resulting integers. How is such a situation typically handled in
C++?
I usually write a simple round function, e.g.

int round(double x)
{
return static_cast<int>(d > 0 ? d + 0.5 : d - 0.5);
}

The 'automagic' conversion truncates towords zero, e.g.

1.9 ==> 1
-0.8 ==> 0

which doesn't sound like what you want.

So far as I know there is no explicit round() function native to C++ that
will round a float or double to an int or size_t. Is this correct?


Yes, presumably because there are several issues here. For instance which
algorithm to use for rounding (the above is only one possible), and how to
deal with overflow (which I've ignored above).

john
Jul 22 '05 #2

"John Harrison" <jo*************@hotmail.com> wrote in message
news:opsajzq9mf212331@andronicus...
You should normally use doubles. I can't see any reason not to in your
code. Obviously doubles have more precision and greater range, but
(apparently) on floating point hardware they are as fast as if, not
faster, than floats. So the only reason to use floats is to save space,
which isn't the case for your code.


In fact, there is a real performance difference. Once I had to write FFT
(fast fourier transform) algorithm in C++, and version which used
float numbers worked about 2.5 times faster than version which used
double numbers. If it matters, PC was based on AMD Duron processor,
and compiler was from Borland C++ Builder 5.
Jul 22 '05 #3
John Harrison wrote:

You should normally use doubles. I can't see any reason not to in your
code. Obviously doubles have more precision and greater range, but
(apparently) on floating point hardware they are as fast as if, not
faster, than floats. So the only reason to use floats is to save space,
which isn't the case for your code.
I'm not even sure why I was using float there. Perhaps I just followed some
sample code. I've found a lot of C++ stuff uses floats where I would have
expected doubles. I will keep this issue in mind. My guess is the
performance impact could well be sensitive to the hardware, compiler, and
context. (ACK: I have read Sergey's response).
I usually write a simple round function, e.g.

int round(double x)
{
return static_cast<int>(d > 0 ? d + 0.5 : d - 0.5);
}

The 'automagic' conversion truncates towords zero, e.g.

1.9 ==> 1
-0.8 ==> 0

which doesn't sound like what you want.


I'm under the impression this is implementation dependent. I've only
glanced at the discussion, but it looks like the rounding style is part of
the descriptive datastructure required by the Standard. I'm looking at
18.2.1
namespace std {
template<class T> class numeric_limits {
public:
static const bool is_specialized = false;
static T min() throw();
static T max() throw();
static const int digits = 0;
static const int digits10 = 0;
static const bool is_signed = false;
static const bool is_integer = false;
static const bool is_exact = false;
static const int radix = 0;
static T epsilon() throw();
static T round_error() throw();
static const int min_exponent = 0;
static const int min_exponent10 = 0;
static const int max_exponent = 0;
static const int max_exponent10 = 0;
static const bool has_infinity = false;
static const bool has_quiet_NaN = false;
static const bool has_signaling_NaN = false;
static const float_denorm_style has_denorm = denorm_absent;
static const bool has_denorm_loss = false;
static T infinity() throw();
static T quiet_NaN() throw();
static T signaling_NaN() throw();
static T denorm_min() throw();
static const bool is_iec559 = false;
static const bool is_bounded = false;
static const bool is_modulo = false;
static const bool traps = false;
static const bool tinyness_before = false;
static const float_round_style round_style = round_toward_zero;
};
}
...

static const float_round_style round_style;
63 The rounding style for the type.206)

64 Meaningful for all floating point types. Specializations for integer
types shall return round_toward_zero.

18.2.1.3 Type float_round_style
namespace std {
enum float_round_style {
round_indeterminate = -1,
round_toward_zero = 0,
round_to_nearest = 1,
round_toward_infinity = 2,
round_toward_neg_infinity =3
};
}

So far as I know there is no explicit round() function native to C++ that
will round a float or double to an int or size_t. Is this correct?


Yes, presumably because there are several issues here. For instance which
algorithm to use for rounding (the above is only one possible), and how to
deal with overflow (which I've ignored above).

john


For now I think I'll buy the quick and dirty default behavior. If I can see
the consequence in the graphics, I'll consider a better solution.

--
STH
Hatton's Law: "There is only One inviolable Law"
KDevelop: http://www.kdevelop.org SuSE: http://www.suse.com
Mozilla: http://www.mozilla.org
Jul 22 '05 #4
On Sat, 03 Jul 2004 09:01:25 -0400, Steven T. Hatton
<su******@setidava.kushan.aa> wrote:
John Harrison wrote:

You should normally use doubles. I can't see any reason not to in your
code. Obviously doubles have more precision and greater range, but
(apparently) on floating point hardware they are as fast as if, not
faster, than floats. So the only reason to use floats is to save space,
which isn't the case for your code.
I'm not even sure why I was using float there. Perhaps I just followed
some
sample code. I've found a lot of C++ stuff uses floats where I would
have
expected doubles. I will keep this issue in mind. My guess is the
performance impact could well be sensitive to the hardware, compiler, and
context. (ACK: I have read Sergey's response).


I'm sure that's right.
I usually write a simple round function, e.g.

int round(double x)
{
return static_cast<int>(d > 0 ? d + 0.5 : d - 0.5);
}

The 'automagic' conversion truncates towords zero, e.g.

1.9 ==> 1
-0.8 ==> 0

which doesn't sound like what you want.
I'm under the impression this is implementation dependent. I've only
glanced at the discussion, but it looks like the rounding style is part
of
the descriptive datastructure required by the Standard. I'm looking at
18.2.1


[snip]


This is covered explicitly in 4.9 para 1, 'An rvalue of a floating point
type can be converted to an rvalue of an integer type. The conversion
truncates; that is, the fractional part is discarded.'


So far as I know there is no explicit round() function native to
C++ that
will round a float or double to an int or size_t. Is this correct?


Yes, presumably because there are several issues here. For instance
which
algorithm to use for rounding (the above is only one possible), and how
to
deal with overflow (which I've ignored above).

john


For now I think I'll buy the quick and dirty default behavior. If I can
see
the consequence in the graphics, I'll consider a better solution.


john
Jul 22 '05 #5

Steven T. Hatton wrote:
guess I have some choices as to whether I pass the floating point values
and let the conversion take place automagically, or convert first and then
pass the resulting integers. How is such a situation typically handled in
C++?
it's been a long, long time since i've had to do any serious math
programming that involved converting to integers. but i seem to recall
that standard behavour is simple truncation.

1.1 -> 1
1.9 -> 1
0.1 -> 0
0.9 -> 0

aka rounding towards 0.
So far as I know there is no explicit round() function native to C++ that
will round a float or double to an int or size_t. Is this correct?
i honestly can't remember, but it's easy enough to emulate:

// not considering -ve
double round(double d)
{
return (fmod(d, 1.0) > 0.5) ? ceil(d) : floor(d);
}

i remember once for some reason we did one that was something like this:

// not considering -ve, this is just a vague memory
double round(double d)
{
double r = fmod(fabs(d), 2.0);
if (r >= 1.0) // odd
{
return (r > 1.5) ? ceil(d) : floor(d);
}
else // even
{
return (r >= 0.5) ? ceil(d) : floor(d);
}
}

though i can't remember why. i think it was required by a prof. these
days i don't exactly strive for techincal accuracy. close enough is good
enough.

if you want speed, and you know you're converting anyway, you might want
to just write a conversion function.

int double_to_int(double d)
{
if (fmod(fabs(d), 1.0) > 0.5)
{
int i = int(d);
return i < 0 ? --i : ++i;
}
else
{
return int(d);
}
}
namespace drawings
{
static float pi = acos(-1.0f); // not sure if static is right here.


no, not really, more like const. but have you ruled out M_PI?

mark

Jul 22 '05 #6
Sergey Khoroshavin wrote:
"John Harrison" <jo*************@hotmail.com> wrote in message
news:opsajzq9mf212331@andronicus...
You should normally use doubles. I can't see any reason not to in your
code. Obviously doubles have more precision and greater range, but
(apparently) on floating point hardware they are as fast as if, not
faster, than floats. So the only reason to use floats is to save space,
which isn't the case for your code.


In fact, there is a real performance difference. Once I had to write FFT
(fast fourier transform) algorithm in C++, and version which used
float numbers worked about 2.5 times faster than version which used
double numbers. If it matters, PC was based on AMD Duron processor,
and compiler was from Borland C++ Builder 5.


One possible reason for the speed difference is that floats use less
memory. Therefore floats are less likely to trash the cache and consume
less memory bandwidth, which is a concern when the clockspeed of the
processor is much higher than the memory.

--
Peter van Merkerk
peter.van.merkerk(at)dse.nl
Jul 22 '05 #7
In message <it********************@speakeasy.net>, Steven T. Hatton
<su******@setidava.kushan.aa> writes
John Harrison wrote:

You should normally use doubles. I can't see any reason not to in your
code. Obviously doubles have more precision and greater range, but
(apparently) on floating point hardware they are as fast as if, not
faster, than floats. So the only reason to use floats is to save space,
which isn't the case for your code.


I'm not even sure why I was using float there. Perhaps I just followed some
sample code. I've found a lot of C++ stuff uses floats where I would have
expected doubles. I will keep this issue in mind. My guess is the
performance impact could well be sensitive to the hardware, compiler, and
context. (ACK: I have read Sergey's response).
I usually write a simple round function, e.g.

int round(double x)
{
return static_cast<int>(d > 0 ? d + 0.5 : d - 0.5);
}

The 'automagic' conversion truncates towords zero, e.g.

1.9 ==> 1
-0.8 ==> 0

which doesn't sound like what you want.


I'm under the impression this is implementation dependent. I've only
glanced at the discussion, but it looks like the rounding style is part of
the descriptive datastructure required by the Standard.


"Rounding style" refers to what it does when a calculation produces more
digits than it can store, not how it converts float to int, which, as
John Harrison pointed out, is well defined in 4.9.

PS Although there's no std::round, don't overlook std::floor and
std::ceil, which are useful for some other calculations.

--
Richard Herring
Jul 22 '05 #8

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

Similar topics

0
by: David Goodger | last post by:
With apologies in advance to the devoutly religious among us, who may be offended by this corruption of The Lord's Prayer. No offence intended. The Pythonista's Prayer =======================...
14
by: calan | last post by:
Does anyone have a function that will round a number to 0 or .5? I have a form where I'm entering a number in inches. I need to round it to the nearest 1/2 inch (onChange). The split will be...
4
by: spebola | last post by:
I am using vb.net 2003 professional and I get the following results when using the round method: dim Amount as decimal = 180.255 Amount = Amount.Round(Amount, 2) Amount now contains 180.25. ...
8
by: Zorpiedoman | last post by:
Howcome: Dim D as decimal = .5D msgbox d.Round(D, 0) this returns "0" Now when I went to school .5 rounds UP to 1 not DOWN to zero?????!!! Documentation says this, but what the heck are...
2
by: Jiri Nemec | last post by:
Hello all, I have got one table with rounding values, table contains prices and round types. id price_from price_to rounding 1 0 1500 0.1 2 1500 ...
11
by: cj | last post by:
Lets assume all calculations are done with decimal data types so things are as precise as possible. When it comes to the final rounding to cut a check to pay dividends for example in VB rounding...
18
by: jdrott1 | last post by:
i'm trying to round my currency string to end in 9. it's for a pricing application. this is the function i'm using to get the item in currency: FormatCurrency(BoxCost, , , , TriState.True) if...
206
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) ...
20
by: jacob navia | last post by:
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>
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
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,...
0
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...
0
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,...
0
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...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

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.