Vissza

JavaScript hibák matematikában.


Matematika alapismeretek


Matematikai hibák


A tizedek nem ábrázolhatóak pontosan kettes számrendszerben, mert 1/10 = 1/(2*5), tehát nem 2 hatványa.
Ez miatt, sem a 0,1, sem a 0,2 nem ábrázolható pontosan, csak közelítőleg.
Összegük a kerekítési hiba miatt, nem adja ki a 0,3 értéket, hanem 0,30000000000000004-et kapunk.
( A tízes számrendszerben is pont azok a törtek ábrázolhatóak pontosan, amelyek nevezőjének prímtényezői 2 és 5.
Minden másból végtelen, szakaszos tizedes tört lesz. )


JavaScript matematikában:
Egészszámokkal jól dolgozik.
Számérték tizedes számokat is tartalmaz, előfordul hibás matematikai eredmény.
Példa:
0.1 + 0.1 + 0.1 = 0.3 ------ Eredmény ez lesz: 0.30000000000000004
1.1 + 1.1 + 1.1 = 3.3 ------ Eredmény ez lesz: 3.3000000000000003
3 * 0.1 = 0.3 ----------------- Eredmény ez lesz: 0.30000000000000004
0.2+0.1 = 0.3 --------------- Eredmény ez lesz: 0.30000000000000004

Mondhatjuk, hogy matematikában ezek az eltérések olyan kicsik, hogy elhanyagolhatók.
De ezek a kis hibák, programfutás szempontjából hibához vezetnek.
Programfutás szempontjából miért fontosak a pontos adatok, lentebb erre is láthatunk példát.


JavaSript összeadás eredményei.

Egészszámokra jó.
Ha 0.1 tizedet összeadunk, 3 szor; 8 szor; 9 szer; Nem kapunk pontos eredményt.

JavaSript kivonás eredményei.

Ha 0.1 tizedet kivonunk, 5 ször; Nem kapunk pontos eredményt.

JavaSript szorzás, osztás, eredményei.

Ha 0.1 tizedet szorzunk, 3-al; 6-al; 7-el; Nem kapunk pontos eredményt.
Ha 0.3-at; 0.6-ot; 0.7-et; 0.1 tizeddel osztunk. Nem kapunk pontos eredményt.

For ciklus eredményei.

Egészszámokra jó.
0.1-tizednél vagy 0.01 századnál, hibás eredményekkel is találkozunk.

Lépték: 1.
for(i=0; i<16; i++){
$("#Fori").append(i+'<br>');
}

Lépték: 0.1 tized.
for(i=0; i<1.6; i=i+0.1){
$("#Fori1").append(i+'<br>');
}

Lépték: 0.01 század.
for(i=0; i<0.16; i=i+0.01){
$("#Fori2").append(i+'<br>');
}



Programfutás szempontjából, miért fontosak a pontos adatok.

Példa:
Létrehozunk egy tömböt, melyet feltöltünk 0.1-tizedes léptékű adatokkal.
Egy " if " feltételnél meghatározzuk, ha a tömbben talál 0.3-tizedes értéket, akkor milyen műveletet végezzen el.

1.Példa:
Alapértelmezett program,
melynél több esetben sem teljesülne
az if feltételben meghatározott ellenőrzés:

var szamok = new Array();
var esz=0;      // Elemek számozása.
// Lépték 0.1 tized. ---------------------------------
 for(i=0; i<1.5; i=i+0.1){ szamok[esz]=i;  esz++; }
var tombhossza= szamok.length;
 
// Tömb bejárása:
 for(i=0; i<tombhossza; i++){
	 szam=szamok[i];
	 if(szam == 0.3 || szam==0.8 || szam==0.9) { 
                       var eredmeny='<mark>Keresett  adattal, van egyezés.</mark>'; 
	                   $("#keresett").append(eredmeny+'<br>');}
	 else{ var eredmeny='Keresett adattal, <mark>nincs</mark> egyezés.'; 
	                   $("#keresett").append(eredmeny+'<br>');}    
 }
 
Tömb adatai:

Keresés eredménye:

2.Példa:
Módosított program,
melynél tizedesre kerekítést alkalmazzuk, így már
teljesül az if feltételben meghatározott ellenőrzés:

var szamok = new Array();
var esz=0;      // Elemek számozása.
// Lépték 0.1 tized. ---------------------------------
 for(i=0; i<1.5; i=i+0.1){
    var szazszor=i*100;                             // Százzal felszorozzuk.
    var egeszre= parseInt(szazszor);          // Egész-számok kellenek.
    var tizzel=egeszre/10;                          // Egészszámot 10-el osztjuk.
    var kerekit= Math.ceil(tizzel);             // Felfelé kerekítünk.
    var tizedesre=kerekit/10;                      // Kerekített számot 10-el osztjuk.
    szamok[esz]=tizedesre;                         // Eredményt, tömbbe íratjuk.
    esz++;  
 }
    var tombhossza= szamok.length;
// Tömb bejárása:
 for(i=0; i<tombhossza; i++){
	 szam=szamok[i];
	 if(szam == 0.3 || szam==0.8 || szam==0.9) { 
                  var eredmeny='<mark>Keresett adattal, van egyezés.</mark>'; 
	              $("#keresett").append(eredmeny+'<br>');
               }
	 else{ var eredmeny='Keresett adattal, nincs egyezés.'; 
	                   $("#keresett").append(eredmeny+'<br>');
                }    
 }
 
Tömb adatai:

Keresés eredménye:




Alapértelmezett műveletek nem egészszámokkal

<!DOCTYPE html>
<html lang="hu">
<head>
<meta charset="UTF-8">
<title>JavaScript hibái matematikában.</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
</head>
<body>
<table class="jsmatek">
<tr> <td>Lépték: 1.1 </td> </tr>
<tr> <td> <span id="tombadat"></span> </td> </tr>
</table>
<script type="text/javascript"  language="javascript" src="matematika.js"></script>
</body>
</html>

matematika.js programunk.

$(document).ready(function(){
   var tomb = new Array();
   var esz=0;
   // Lépték 1.1  ---------------------------------
   for(i=0; i<12; i=i+1.1) {  tomb[esz]=i;   esz++;  }
        var tombhossza= tomb.length; 
   // Tömb bejárása:
   for(i=0; i<tombhossza; i++) {  szam=tomb[i];   $("#tombadat").append(szam+'<br>');    }
});
Lépték: 1Lépték: 1.1Lépték: 1.2Lépték: 1.3Lépték: 1.4





Lépték: 1.5Lépték: 1.6Lépték: 1.7Lépték: 1.8Lépték: 1.9







Pontos adatokat kapjunk nem egészszámoknál,
tizedesre történő kerekítést alkalmazzuk

matematika.js programunk.

$(document).ready(function(){
   var tomb = new Array();
   var esz=0;
   // Lépték 1.1  ---------------------------------
   for(i=0; i<12; i=i+1.1) {
       var szorzas=i*100;                              // Egy tizedesre: Értéket, százzal felszorozzuk.
       var egeszre= parseInt(szorzas);         // Csak az egészszámok kellenek.
       var tizzel=egeszre/10;                         // Egészszámokat 10-el osztjuk.
       var kerekit= Math.ceil(tizzel);              // Felfelé kerekítünk.
       var tizedesre=kerekit/10;                    // Kerekített értéket, 10-el osztjuk.
     tomb[esz]=tizedesre;                             // Kapott értéket, tömbbe íratjuk.
     esz++;
   }
        var tombhossza= tomb.length; 
   // Tömb bejárása:
   for(i=0; i<tombhossza; i++) {  szam=tomb[i];   $("#tombadat").append(szam+'<br>');    }
});
Lépték: 1Lépték: 1.1Lépték: 1.2Lépték: 1.3Lépték: 1.4





Lépték: 1.5Lépték: 1.6Lépték: 1.7Lépték: 1.8Lépték: 1.9







Kerekítések tizedes számokat is tartalmazó
matematikai műveleteknél.

Kerekités: 1 tizedesre:
3 * 1.1; vagy 1.1 + 1.1 + 1.1 = 3.3
var ertek = 1.1+1.1+1.1; 
  $("#nemkerekitett").append(ertek);         // Kerekítés nélküli érték kiíratása.
       var szorzas=ertek*100;                         // Értéket, százzal felszorozzuk.
       var egesz= parseInt(szorzas);             // Csak az egészszámok kellenek.
       var osztas=egesz/10;                            // Egészszámokat 10-el osztjuk.
       var kerekit= Math.ceil(osztas);             // Felfelé kerekítünk.
       var tizedesre=kerekit/10;                      // Kerekített értéket, 10-el osztjuk.
  $("#kerekitett").append(tizedesre);          // Kerekített érték kiíratása.

Program eredménye:

Kerekítés nélkül =
Kerekítve =

Kerekités: 2 tizedesre:
3 * 1.01; vagy 1.01+1.01+1.01 = 3.03
var ertek = 1.01+1.01+1.01; 
  $("#nemkerekitett").append(ertek);         // Kerekítés nélküli érték kiíratása.
       var szorzas=ertek*1000;                        // Értéket, ezerrel felszorozzuk.
       var egesz= parseInt(szorzas);             // Csak az egészszámok kellenek.
       var osztas=egesz/10;                            // Egészszámokat 10-el osztjuk.
       var kerekit= Math.ceil(osztas);             // Felfelé kerekítünk.
       var tizedesre=kerekit/100;                     // Kerekített értéket, 100-al osztjuk.
  $("#kerekitett").append(tizedesre);          // Kerekített érték kiíratása.

Program eredménye:

Kerekítés nélkül =
Kerekítve =

Kerekités: 3 tizedesre: 1.001+1.001+1.001 = 3.003
var ertek = 1.001+1.001+1.001; 
  $("#nemkerekitett").append(ertek);         // Kerekítés nélküli érték kiíratása.
       var szorzas=ertek*10000;                       // Értéket, tízezerrel felszorozzuk.
       var egesz= parseInt(szorzas);             // Csak az egészszámok kellenek.
       var osztas=egesz/10;                            // Egészszámokat 10-el osztjuk.
       var kerekit= Math.ceil(osztas);             // Felfelé kerekítünk.
       var tizedesre=kerekit/1000;                    // Kerekített értéket, 1000-el osztjuk.
  $("#kerekitett").append(tizedesre);          // Kerekített érték kiíratása.

Program eredménye:

Kerekítés nélkül =
Kerekítve =

Kerekités: 4 tizedesre: 3 * 0.0001 = 0.0003
var ertek = 3*0.0001; 
  $("#nemkerekitett").append(ertek);         // Kerekítés nélküli érték kiíratása.
       var szorzas=ertek*100000;                      // Értéket, százezerrel felszorozzuk.
       var egesz= parseInt(szorzas);             // Csak az egészszámok kellenek.
       var osztas=egesz/10;                            // Egészszámokat 10-el osztjuk.
       var kerekit= Math.ceil(osztas);             // Felfelé kerekítünk.
       var tizedesre=kerekit/10000;                   // Kerekített értéket, 10000-el osztjuk.
  $("#kerekitett").append(tizedesre);          // Kerekített érték kiíratása.

Program eredménye:

Kerekítés nélkül =
Kerekítve =