473,549 Members | 2,455 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Scientific notation - no rounding errors?

Hi all,

Math is not my strongest area so forgive me if I use some of the wrong
terminology.
It seems that scientific notation is immune to rounding errors. For
example:

(4.98 * 100) + 5.51 // returns 503.51000000000 005, rounding error!
4.98e2 + 5.51 // returns 503.51, correct!

Why are scientific notation numbers not affected? And if this is true,
does this mean that scientific notation would be safe to use in a
floating-point addition function?

For example, 4.98 + 0.2, which comes out to 5.1800000000000 01
(incorrect!), would become (498e2 + 0.2e2) / 1e2, which comes out to
5.18 (correct!)

Any insight would be appreciated...

--
Joe

May 16 '06 #1
9 6617
Joe Attardi wrote on 16 mei 2006 in comp.lang.javas cript:
Math is not my strongest area so forgive me if I use some of the wrong
terminology.
It seems that scientific notation is immune to rounding errors. For
example:

(4.98 * 100) + 5.51 // returns 503.51000000000 005, rounding error!
4.98e2 + 5.51 // returns 503.51, correct!

Why are scientific notation numbers not affected?
Wrong, it is untrue.
And if this is true,
does this mean that scientific notation would be safe to use in a
floating-point addition function?
Unanswerable.
For example, 4.98 + 0.2, which comes out to 5.1800000000000 01
(incorrect!), would become (498e2 + 0.2e2) / 1e2, which comes out to
5.18 (correct!)
Only a single negative example can prove a point [to be incorrect],
while any finite number of positive examples is not enough for
correctness.

<http://en.wikipedia.or g/wiki/Reductio_ad_abs urdum>
Any insight would be appreciated...


Javascript arythmetic and storage use binary [=base 2] numbers.
All fraction numbers or results that are not exact floating point
binaries could introduce rounding errors, seen from a decimal world, or
through overflow of the mantissa.

So decimal 0.5 and 5e-1 are both exactly binary 0.1 and will make no
problems. 0.2 or 2e-1 [1/5] already gives me the creeps binary.

--
Evertjan.
The Netherlands.
(Please change the x'es to dots in my emailaddress)
May 16 '06 #2
Evertjan. wrote:
(4.98 * 100) + 5.51 // returns 503.51000000000 005, rounding error!
4.98e2 + 5.51 // returns 503.51, correct!
Why are scientific notation numbers not affected?
Wrong, it is untrue.

If it is untrue, then why do the two examples come out with different
values?
Only a single negative example can prove a point [to be incorrect],
while any finite number of positive examples is not enough for
correctness. I realize that. I'm not trying to do a proof here, I'm just asking for
advice.
Javascript arythmetic and storage use binary [=base 2] numbers.
All fraction numbers or results that are not exact floating point
binaries could introduce rounding errors, seen from a decimal world, or
through overflow of the mantissa.

So what can I do to properly show the sum of an addition?
The point of trying to use the scientific notation is to do what I
think is called scaled integer arithmetic? That is, 4.98 + 0.2 becomes
498 + 20, then the addition is integer addition, then the result is
divided back down for the correct result.

If using multiplication and division to move the decimal point won't
work, due to the floating point inaccuracies, what about (I know this
sounds messy) converting them to strings, counting the decimal places
in the string, removing the decimal point from the string, convert back
to numbers, perform the calculations, and merely insert a decimal point
in the string of the result?

I know that sounds inefficient but it at least would get a proper
result, I think.

May 16 '06 #3
Rob
This problem is not limited to JavaSript. You may want to bone up on
the subject in a general cs book. There are a number of solutions to
handle rounding errors and I'm sure I don't know half of them. Your
solution of scaling the number, truncating to an integer and then
scaling back is one. The truncation hides the round off error.

The best solution is to format the numbers to show only the number of
significant digits your application requires. This hides the rounding
errors. It's up to you to design your application so that these errors
do not accumulate until a noticeable error occurs. If you use a
spreadsheet, these same factors apply. They just don't show you all the
digits by default. That's how the errors are hidden in a spreadsheet.

Rob:-]

May 16 '06 #4

Joe Attardi wrote:
Hi all,

Math is not my strongest area so forgive me if I use some of the wrong
terminology.
It seems that scientific notation is immune to rounding errors. For
example:

(4.98 * 100) + 5.51 // returns 503.51000000000 005, rounding error!
4.98e2 + 5.51 // returns 503.51, correct!

Why are scientific notation numbers not affected? And if this is true,
does this mean that scientific notation would be safe to use in a
floating-point addition function?

For example, 4.98 + 0.2, which comes out to 5.1800000000000 01
(incorrect!), would become (498e2 + 0.2e2) / 1e2, which comes out to
5.18 (correct!)

Any insight would be appreciated...


Modern computers use number systems based on 2 or powers thereof such
as 2(binary), 4, 8(octal), 16(hex), 32, 64, 128 and so on. Most western
math is on a base 10 system. Anytime you convert from one number system
to another, there are going to be some errors introduced, as non-exact
numbers result in some cases. If you use decimals and allow division,
this ensures some numbers can not be represented exactly in some
systems. Consider that in the ordinary base 10 number system, division
of 1 by 3 gives a decimal number .33333 to infinity that can not be
written exactly.

The reason for the scientific number system is that some huge and very
small numbers are often used, and you do not want to have to write a
lot of leading or trailing zeros to do calculations. Some scientifc
calculations, if not very carefully programmed, will cause underflows
or overflows even if the computer can handle exp(100).

The 'funny" roundoffs have been with computing for well over 50 years
since digital computers based on a binary system were introduced, and
methods for handling this have been around just as long. People that
did money calculations soon started using cents rather than dollars in
the US so that fractions were avoided in additions and subtractions so
that "funny" numbers such as $1.00000001 would not disturb the bean
counters. In fact IBM had two different programs systems that were
widely used. Fortran was used for scientific calculations, and Cobal
was used for money calculations.

May 16 '06 #5
Rob
Here's a nice set of JavaScript techniques to deal with the problem:

http://www.mredkj.com/javascript/numberFormat.html

Or for a more rigorous treatment of the subject:

http://docs.sun.com/source/806-3568/ncg_goldberg.html

May 16 '06 #6
Rob
var num = 10;
var result = num.toFixed(2); // result will equal 10.00

num = 930.9805;
result = num.toFixed(3); // result will equal 930.981

num = 500.2349;
result = num.toPrecision (4); // result will equal 500.2

num = 5000.2349;
result = num.toPrecision (4); // result will equal 5000

num = 555.55;
result = num.toPrecision (2); // result will equal 5.6e+2

May 16 '06 #7
Rob wrote:
The best solution is to format the numbers to show only the number of
significant digits your application requires.


I basically need to compare a maximum to a computed total. The maximum
isn't known until runtime. So, to get the number of decimal places I
need, I could just count the number of decimal places in the maximum
and round the computed total to that many places?

May 16 '06 #8
"Joe Attardi" <ja******@gmail .com> writes:
Evertjan. wrote:
> (4.98 * 100) + 5.51 // returns 503.51000000000 005, rounding error!
> 4.98e2 + 5.51 // returns 503.51, correct!
> Why are scientific notation numbers not affected?
Wrong, it is untrue.

If it is untrue, then why do the two examples come out with different
values?


Because 498 (aka. 4.98e2) can be represented exactly in the
representation used by Javascript's number type, but 4.98 cannot.

When you write 498 or 4.98e2 you get exactly that value.

The literal "4.98" does not give exactly the value 4.98, but rather
the representable value that is closest to that number. There is a
difference. When you then multiply by 100, the difference is also
multiplied, making it even more visible.
So what can I do to properly show the sum of an addition?
More importantly, how can you ensure that each operand of the
addition is exactly the number you expect? Generally, you can't.
The point of trying to use the scientific notation is to do what I
think is called scaled integer arithmetic? That is, 4.98 + 0.2 becomes
498 + 20, then the addition is integer addition, then the result is
divided back down for the correct result.
I don't know the name, but the approach is sound (as long as you
don't get results so big that they loose precission, i.e., something
that cannot be represented with 53 bits preission).
If using multiplication and division to move the decimal point won't
work, due to the floating point inaccuracies, what about (I know this
sounds messy) converting them to strings, counting the decimal places
in the string, removing the decimal point from the string, convert back
to numbers, perform the calculations, and merely insert a decimal point
in the string of the result?


Workable. You could also start out with two integer literals, one
for the number without the decimal point and one the position of
the point. Harder to read, but saves parsing the string.

Or you could create your own decimal number representation. Something
like:
---
function Dec(n,mag) {
this.n = Math.floor(n);
this.mag = Math.floor(mag) ;
}
Dec.prototype.a dd = function add(dec) {
if (this.mag < dec.mag) {
return dec.add(this);
}
var diff = this.mag - dec.mag;
return new Dec(this.n + Math.pow(10,dif f) * dec.n, this.mag);
};
Dec.prototype.m ult = function mult(dec) {
return new Dec(this.n * dec.n, this.mag + dec.mag);
};
Dec.prototype.t oString = function toString() {
var n = this.n;
var mag = this.mag;
var res = [];
var sign = "";
if (n < 0) {
n = -n;
sign = "-";
}
while(mag > 0) {
res.push("0");
mag--;
}
while(n > 0) {
res.push(String (n%10));
n = Math.floor(n / 10);
mag++;
if (mag == 0) {
res.push(".");
}
}
while(mag < 0) {
res.push("0");
mag ++;
if (mag == 0) {
res.push(".");
}
}
res.push(sign);
return res.reverse().j oin("");
};

var d1 = new Dec(5); // 5.0
var d2 = new Dec(5,-1); // 0.5
var d3 = new Dec(5,1); //50.0
alert([d1.mult(d2),
d1.mult(d3),
d3.mult(d3),
d2.mult(d2)]); // 2.5,250,2500,.2 5

---
Div and mod are the harder ones. You must still beware of overflow.

Good luck
/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleD OM.html>
'Faith without judgement merely degrades the spirit divine.'
May 16 '06 #9
JRS: In article <11************ **********@j33g 2000cwa.googleg roups.com>
, dated Tue, 16 May 2006 10:16:56 remote, seen in
news:comp.lang. javascript, Joe Attardi <ja******@gmail .com> posted :
Math is not my strongest area so forgive me if I use some of the wrong
terminology.
It seems that scientific notation is immune to rounding errors. For
example:

(4.98 * 100) + 5.51 // returns 503.51000000000 005, rounding error!
4.98e2 + 5.51 // returns 503.51, correct!
But that is a simpler calculation, one operation instead of two.
4.98*100 does not show 498.

Why are scientific notation numbers not affected? And if this is true,
does this mean that scientific notation would be safe to use in a
floating-point addition function?

For example, 4.98 + 0.2, which comes out to 5.1800000000000 01
(incorrect!) , would become (498e2 + 0.2e2) / 1e2, which comes out to
5.18 (correct!)
It does not come out to 5.18, since a Number, being an IEEE Double,
cannot represent 5.18 exactly. However, conversion to String, for
output, would give something so close to 5.18 that 5.18 would be shown.

Now 5, being an integer no bigger than 2^53, is held exactly;
and 5.18-5 gives 0.1799999999999 9971
and (5.18-5)*100-18 gives -2.8421709430404 01e-14

A value exact in cents but handled as euros.cents will generally be
represented inexactly, and arithmetic will generally introduce further
error. But if the work is done in cents, it will be done without error.

I think an exact number of cents divided by 100 and converted to String
will be shown as you would wish, except for suppression of trailing
zeroes; it would be better to convert the integer to String and insert
the decimal point by character manipulation (e.g. RegExp .replace).

Note that multiplication by 0.01 gives inexact results, since 0.01
cannot be held exactly -
try for (J=0; J<1111; J++) document.writel n(J / 100, '<br>')
and for (J=0; J<1111; J++) document.writel n(J * 0.01, '<br>')

Any insight would be appreciated...


Read the newsgroup FAQ, sections 4.7, 4.6; read <URL:http://www.merlyn.
demon.co.uk/js-maths.htm> and follow links therein.

--
© John Stockton, Surrey, UK. ?@merlyn.demon. co.uk Turnpike v4.00 IE 4 ©
<URL:http://www.jibbering.c om/faq/> JL/RC: FAQ of news:comp.lang. javascript
<URL:http://www.merlyn.demo n.co.uk/js-index.htm> jscr maths, dates, sources.
<URL:http://www.merlyn.demo n.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.
May 16 '06 #10

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

Similar topics

2
8703
by: Woodster | last post by:
I am using the std::setprecision function to format variables of type double in a string however I am unsure how to stop this appearing in scientific notation. For example std::stringstream buffer; buffer << setprecision(1) << 40.0 << "° C";
1
2032
by: masoud bayan | last post by:
I have some values in type of double such 0.00009 , 0.0000007, when I want to show them in a text box and convert them to string they are changed to scientific notation while I want to show them as they are. I tried to use tostring("f") but it needs to have a precision number after *f* which will cause always have fix number of characters...
1
8811
by: Nick | last post by:
Well, the project I am working on has now come to a screeching halt! I have been developing a program that heavily utilizes ADO.NET record sets. To generate reports, I convert the recordset to XML, and then apply an XSLT to transform the XML into HTML. This works great (or did) until today. I just found out that the "number-format" command in...
0
1680
by: Greg | last post by:
I am working on an application that requires working with numbers in scientific notation. I am using SqlServer as the database and I have created strongly typed data adapters and datasets. The numbers are defined as numeric in the SqlServer Database and are bound to text boxes in the app. In the dataset xml these numbers are defined as...
7
10891
by: Dustan | last post by:
How can I get a number into scientific notation? I have a preference for the format '1 E 50' (as an example), but if it's well known, it works.
2
7245
by: Ryan Liu | last post by:
In C#, for a large float (9 digitals), how can I disable Scientific notation. When it auto convert to Scientific notation, I lost accuracy. Thanks a lot! Ryan
2
2753
by: rSmoke | last post by:
I have a DataSet that contains a table with about 6 columns of high accuracy decimal values. When I try to write out the DataSet using the WriteXML() function the XML is written fine, but the decimal values are written out in scientific notation ("9.984348392E+08"). This wouldn't be a problem except when I try to READ the XML file back into a...
7
2127
by: grinder | last post by:
I have a program that fits a line to data points. The question is: can 'C' understand scientific notation (as below) , and if not what can i do to make it work.. 0.000 0.3231E+02 0.0000E+00 0.00 0.5642E+02 13.191 0.3421E+02 0.0000E+00 10.00 0.5910E+02 26.248 0.2842E+02 0.0000E+00 20.00 0.4758E+02
2
7006
by: Greg | last post by:
I am working on an application that requires working with numbers in scientific notation. I am using SqlServer as the database and I have created strongly typed data adapters and datasets. The numbers are defined as numeric in the SqlServer Database and are bound to text boxes in the app. In the dataset's xml these numbers are defined as...
0
7467
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...
0
7982
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...
1
7500
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...
0
7827
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
0
6066
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...
1
5385
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...
0
5110
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...
1
1961
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
1
1079
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.