473,322 Members | 1,480 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,322 software developers and data experts.

Weirdness: (-0.666667 + 0.333333)

Hi,

I'm experiencing some weirdness in a program, when subtracting 2
(double)'s which should result in 0, but instead it returns
-1.11022e-16. It looks to me that changing the double x_step decleration
to unsigned type, might help, but the compiler complains when i try that.

Any ideas ?

#include <iostream>
using namespace std;

int main(int argc, char *argv[]) {

double x1 = -1;
double x2 = 1;
double nx = 6;
int pos = 0;
double x = 0.0;
double x_step = 0.0;

x_step = (x2 - x1) / nx;

x = x1;
for (pos = 0; pos < nx; pos++) {
cout << x << " +\t" << x_step << " =\t " << (x +
x_step) << endl;
x = x + x_step;
}

return 0;
}
Output:

-1 + 0.333333 = -0.666667
-0.666667 + 0.333333 = -0.333333
-0.333333 + 0.333333 = -1.11022e-16
-1.11022e-16 + 0.333333 = 0.333333
0.333333 + 0.333333 = 0.666667
0.666667 + 0.333333 = 1

Jul 22 '05 #1
15 2149
Corne' Cornelius <co****@nospam-for-noreason.uy> wrote in
news:P6********************@is.co.za:
Hi,

I'm experiencing some weirdness in a program, when subtracting 2
(double)'s which should result in 0, but instead it returns
-1.11022e-16. It looks to me that changing the double x_step decleration
to unsigned type, might help, but the compiler complains when i try that.

Any ideas ?


That's the nature of floating point arithmetic. You shouldn't compare
against exact values, beacause of rounding errors (which are unavoidable,
though usually very small).

You should check against some small epsilon range instead of comparing
exact numbers.

--
:: bartekd [at] o2 [dot] pl

Jul 22 '05 #2
I've rounded the x_step var to a couple of places after the decimal
point which seem to help, i need a number closer to 0 then what the
overflow results in.

Thanks !

bartek wrote:
Corne' Cornelius <co****@nospam-for-noreason.uy> wrote in
news:P6********************@is.co.za:

Hi,

I'm experiencing some weirdness in a program, when subtracting 2
(double)'s which should result in 0, but instead it returns
-1.11022e-16. It looks to me that changing the double x_step decleration
to unsigned type, might help, but the compiler complains when i try that.

Any ideas ?

That's the nature of floating point arithmetic. You shouldn't compare
against exact values, beacause of rounding errors (which are unavoidable,
though usually very small).

You should check against some small epsilon range instead of comparing
exact numbers.


Jul 22 '05 #3
Hi!

Corne' Cornelius <co****@nospam-for-noreason.uy> writes:
I'm experiencing some weirdness in a program, when subtracting 2
(double)'s which should result in 0, but instead it returns
-1.11022e-16. It looks to me that changing the double x_step decleration
to unsigned type, might help, but the compiler complains when i try that.


The problem is that real numbers on a computer have limited accuracy.
Results of substracting two real numbers that are (almost) equal, should
not be trusted. Solutions to this problem generally depend on what
exactly you want to do.

Bye,
Chris Dams
Jul 22 '05 #4
Corne' Cornelius wrote:
I'm experiencing some weirdness in a program, when subtracting 2
(double)'s which should result in 0, but instead it returns
-1.11022e-16.


Doubles do not always exactly represent the value of a number but are an
approximation of the value. This is especially true for computed values.

See http://docs.sun.com/source/806-3568/ncg_goldberg.html
Jul 22 '05 #5
Corne' Cornelius <co****@nospam-for-noreason.uy> wrote in
news:-b********************@is.co.za:
I've rounded the x_step var to a couple of places after the decimal
point which seem to help, i need a number closer to 0 then what the
overflow results in.


first...

#include <limits>

....then...

std::numeric_limits<double>::epsilon()

....will give you the smallest possible increment from 1.
Unfortunately rounding errors can be bigger than that.
It all depends on what you're actually doing. You should choose the
threshold based on that.
--
:: bartekd [at] o2 [dot] pl

Jul 22 '05 #6
bartek <sp******************@o2.pl> wrote in
news:Xn**********************************@153.19.2 51.200:
Corne' Cornelius <co****@nospam-for-noreason.uy> wrote in
news:-b********************@is.co.za:
I've rounded the x_step var to a couple of places after the decimal
point which seem to help, i need a number closer to 0 then what the
overflow results in.


first...

#include <limits>

...then...

std::numeric_limits<double>::epsilon()

...will give you the smallest possible increment from 1.
Unfortunately rounding errors can be bigger than that.
It all depends on what you're actually doing. You should choose the
threshold based on that.


I mean -- based on what you're doing, not on numeric_limits::epsilon()
that is.

--
:: bartekd [at] o2 [dot] pl

Jul 22 '05 #7
Bill Seurer wrote:

Doubles do not always exactly represent the value of a number but are an
approximation of the value. This is especially true for computed values.


Doubles exactly represent the value that they hold. They sometimes don't
hold the result that you would get from some computation with infinite
precision arithemetic. But, then, neither do ints. In their first week
future programmers learn to accept that (1/3)*3 isn't 1. For some reason
<g> it's harder for them to accept that with floating point values.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Jul 22 '05 #8
Corne' Cornelius wrote:
Hi,

I'm experiencing some weirdness in a program, when subtracting 2
(double)'s which should result in 0, but instead it returns
-1.11022e-16. It looks to me that changing the double x_step decleration
to unsigned type, might help, but the compiler complains when i try that.

Any ideas ?


Don't compare two floating point numbers as such. Use the trick of an
epsilon interval by Knuth (implemented in the fcmp package available at
sourceforge.net) described in TAOCP Vol 2 Seminumerical algorithms.
bye,
gert
Jul 22 '05 #9
i should've made it more clear what i actually want to do.

I'm not really trying to compare 2 double which could be in accurate
becuase of rounding errors.

I'm writing a program that draws graphs on a cartesian plane, so in
order to go on the x-axis from say -2, to +2, in 20 intervals, i need
one of these point to be zero or very close to it.

how could i make sure i don't get rounding problems ?
Corne' Cornelius wrote:
Hi,

I'm experiencing some weirdness in a program, when subtracting 2
(double)'s which should result in 0, but instead it returns
-1.11022e-16. It looks to me that changing the double x_step decleration
to unsigned type, might help, but the compiler complains when i try that.

Any ideas ?

#include <iostream>
using namespace std;

int main(int argc, char *argv[]) {

double x1 = -1;
double x2 = 1;
double nx = 6;
int pos = 0;
double x = 0.0;
double x_step = 0.0;

x_step = (x2 - x1) / nx;

x = x1;
for (pos = 0; pos < nx; pos++) {
cout << x << " +\t" << x_step << " =\t " << (x +
x_step) << endl;
x = x + x_step;
}

return 0;
}
Output:

-1 + 0.333333 = -0.666667
-0.666667 + 0.333333 = -0.333333
-0.333333 + 0.333333 = -1.11022e-16
-1.11022e-16 + 0.333333 = 0.333333
0.333333 + 0.333333 = 0.666667
0.666667 + 0.333333 = 1


Jul 22 '05 #10
Corne' Cornelius wrote:
i should've made it more clear what i actually want to do.

I'm not really trying to compare 2 double which could be in accurate
becuase of rounding errors.

I'm writing a program that draws graphs on a cartesian plane, so in
order to go on the x-axis from say -2, to +2, in 20 intervals, i need
one of these point to be zero or very close to it.

how could i make sure i don't get rounding problems ?

You can't. The only thing you can do is to compare your value of x to zero
(using fcmp) and if it's close enough force it to be zero. Btw, Is the
difference between 1e-16 and 0.0 so significant that it will show up on a
graph in the range [-1,1] ?

bye,
gert
Jul 22 '05 #11
heh, i also thaught of not worrying about it being 1e-16, but then
there's a pixel missing where x is 0.

Looks like i will have to make 2 loops and 1 statement.

for when:
x - epsilon() < 0
x = 0
x + epsilon() > 0

Gert Van den Eynde wrote:
Corne' Cornelius wrote:

i should've made it more clear what i actually want to do.

I'm not really trying to compare 2 double which could be in accurate
becuase of rounding errors.

I'm writing a program that draws graphs on a cartesian plane, so in
order to go on the x-axis from say -2, to +2, in 20 intervals, i need
one of these point to be zero or very close to it.

how could i make sure i don't get rounding problems ?


You can't. The only thing you can do is to compare your value of x to zero
(using fcmp) and if it's close enough force it to be zero. Btw, Is the
difference between 1e-16 and 0.0 so significant that it will show up on a
graph in the range [-1,1] ?

bye,
gert


Jul 22 '05 #12
Hi!

Corne' Cornelius <co****@nospam-for-noreason.uy> writes:
heh, i also thaught of not worrying about it being 1e-16, but then
there's a pixel missing where x is 0.


If you want to draw a point for every pixels you should loop over pixels
and not over doubles. On the other hand, making small steps and drawing
a straight line between these, is likely to be good enough. Furthermore,
if you draw points for every pixel in the x-direction you should also
worry about what happens if the slope of your graph is bigger than 1.

Bye,
Chris Dams
Jul 22 '05 #13
Corne' Cornelius wrote:

heh, i also thaught of not worrying about it being 1e-16, but then
there's a pixel missing where x is 0.


Then your transformation from world coordinates to
pixel coordinates is in error, if such a small deviation
from 0 makes that effect.

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 22 '05 #14
Karl Heinz Buchegger wrote:

Corne' Cornelius wrote:

heh, i also thaught of not worrying about it being 1e-16, but then
there's a pixel missing where x is 0.


Then your transformation from world coordinates to
pixel coordinates is in error, if such a small deviation
from 0 makes that effect.


The usual error is to truncate instead of round when chopping
of the fractional part in pixel space.

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 22 '05 #15
In message <ZK********************@is.co.za>, Corne' Cornelius
<co****@nospam-for-noreason.uy> writes
i should've made it more clear what i actually want to do.

I'm not really trying to compare 2 double which could be in accurate
becuase of rounding errors.

I'm writing a program that draws graphs on a cartesian plane, so in
order to go on the x-axis from say -2, to +2, in 20 intervals, i need
one of these point to be zero or very close to it.

how could i make sure i don't get rounding problems ?


You can often improve matters by using an integer loop counter:

instead of: for (double x=xstart; x<xend; x+=step) {...}

use something like: for (int i=istart; i<iend; ++i) { double x=i*xstep;
....}

It doesn't get rid of the rounding errors, but it does ensure that they
don't accumulate as you progress through the loop.
--
Richard Herring
Jul 22 '05 #16

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

Similar topics

1
by: (Pete Cresswell) | last post by:
TabControl on the right side of a form with two tabs: Tab #1 contains two subforms that show some dynamic query results. Tab #2 contains a ListView that gets dynamically populated as the user...
0
by: Bruce B | last post by:
Hi group, I'm experiencing some extreme weirdness over the last week with IIS related to it's Mappings and how .NET is behaving. I can't explain the behavior as it seems very random. Our...
1
by: VB Programmer | last post by:
My development machine has been working perfectly, writing ASP.NET apps, etc... I just went to open a project and it said: "Visual Studio .NET has detected that the specified web server is not...
5
by: Phil Weber | last post by:
I'm attempting to debug an ASP.NET Web application in VS.NET 2003. I'm running the app and the debugger on my local machine (Windows XP Professional). I am logged in as a local administrator. In...
5
by: David Thielen | last post by:
Hi; I am creating png files in my ASP .NET app. When I am running under Windows 2003/IIS 6, the file is not given the security permissions it should have. It does not have any permission for...
1
by: rhino | last post by:
I've got some positioning problems that I can't figure out. Can anyone help? My website was working fine in IE7 and the current releases of Firefox and Opera so I had a look at it in IE6 and...
26
by: Prisoner at War | last post by:
Hi, All: I have a JavaScript search engine that always causes MSIE 7 to do a top-of-page security "warning" (that top-of-page-bar, and not an "alert" )...but other websites' JavaScripts do not...
2
by: JYA | last post by:
Hi. I was writing an xmltv parser using python when I faced some weirdness that I couldn't explain. What I'm doing, is read an xml file, create another dom object and copy the element from...
0
by: Dilip | last post by:
I have a weird problem with versioning one of my C# binaries. I have the usual AssemblyVersion/AssemblyFileVersion attributes set. When I use reflector to poke into the compiled binary I can find...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 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 former...

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.