Query generale delle matematiche a virgola mobile

Okay in modo da get che alcuni numbers non possono essere rappresentati correttamente in binario proprio come 1/3 non può essere pienamente rappresentata in decimale.

Quindi come viene quando console.log (0.3) restituisce 0.3 ma quando console.log (0.1 + 0.2) restituisce lo 0.30000000000000004

Come mai conta l'errore (anche se è vero) quando si esegue semplicemente l'output 0.3 ma non quando l'aggiunta si verifica?

Supponiamo di approssimare 1/3 e 2/3 in decimale.

 1/3 = 0.333 2/3 = 0.667 

e aggiungiamo 1/3 + 1/3:

 1/3+1/3 = 0.333 + 0.333 = 0.666 

Non abbiamo ottenuto il nostro approssimazione di 2/3. Arrotondamento 1/3 a qualcosa che possiamo rappresentare in decimale non ha prodotto un numero pari alla metà di quello che abbiamo ottenuto quando abbiamo arrotondato 2/3.

La stessa cosa avviene in binario. Circhiamo 0,1 e 0,2 ai numbers che possiamo rappresentare in binario, ma la sum delle approssimazioni è leggermente diversa da quella che otteniamo se approssimo 0,3. Abbiamo qualcosa di più alto e il risultato viene visualizzato come 0.30000000000000004 .

Le inesattezze nelle rappresentazioni interne di 0.1 e 0.2 sono abbastanza piccole che la printingnte Javascript li ignora quando printing questi numbers. Ma quando li aggiungete le imprecisioni si accumulano, e questo è sufficiente per mostrare quando il risultato viene printingto.

Il modo in cui Java printing numbers a virgola mobile è una parte significativa del comportmento che vedete: per impostazione predefinita, Java non printing il valore esatto di un numero in virgola mobile. Esegue cifre sufficienti per identificare con precisione il double che viene printingto.

Quindi, se impostate x a .3 , x è effettivamente impostato su 0.299999999999999988897769753748434595763683319091796875. Quando Java printing questo, printing solo ".3", poiché la conversione ".3" per double produce il valore di x , 0.299999999999999988897769753748434595763683319091796875.

Quando si utilizza .1 e .2 , questi sono in realtà i valori 0.1000000000000000055511151231257827021181583404541015625 e 0.200000000000000011102230246251565404236316680908203125. Quando li aggiungete (in formato double ), il risultato è 0.3000000000000000444089209850062616169452667236328125.

Quando si printing questo valore, Java printing "0.30000000000000004" perché deve mostrare tutte quelle cifre per produrre un numero che, convertito a double , produrrà 0.3000000000000000444089209850062616169452667236328125.


Ecco la documentazione per la printing dei valori double . Dice:

Quante cifre devono essere printingte per la parte frazionata …? Deve essere presente alless una cifra per rappresentare la parte frazionata, e al di là di quante più, ma solo altrettanti, più cifre necessarie per distinguere in modo univoco il valore di argomento dai valori adiacenti di tipo double .

Come ha detto, nella base 10 non è ansible descrivere con precisione la frazione 1/3. Allo stesso modo, nella base 2, non è ansible descrivere con precisione altre frazioni. Così, quando il computer aggiunge 0.1 e 0.2, sta effettivamente aggiungere qualcosa come 0.10000000001 e 0.20000000003.