Archief - [PROG][JAVA] belachelijk veel cijfers na de komma

Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.

FroFro

Legacy Member
Hoi!

Ik moet een simpele loop maken waarbij elke keer 0.1 bij een variabele wordt opgeteld, maar het vreemde is dat die na enkele tellen compleet de mist ingaat. Hij gaat van 0 -> 0.1 -> 0.2 -> 0.300000000000000000004 etc etc. Hij moet eindigen bij 7, maar das dan weer in de aard van 6.999999. Ik heb heel simpel "t = t + 0.1" gedaan, waarom in godsnaam doet die dan zo raar? :p

Cheers

killgore

Legacy Member
floating point getallen kunnen niet exact worden voorgesteld :). Ook gaan bij bewerkingen vaak gegevens verloren.

je zou beter gehele optelling doen en dan delen door 10.0f voor het kommagetal te zien :p.

Bavo aka Joske

Legacy Member
Dat is de onvoorspelbare wereld van de floating point operaties. Een floating point getal is geen exact getal, maar wel een benadering tot iets wat dat is, of bijna dat is. Dat komt door het bereikt ervan:

int
4 bytes, signed (two's complement). -2,147,483,648 to 2,147,483,647. Like all numeric types ints may be cast into other numeric types (byte, short, long, float, double).

float
4 bytes, IEEE 754. Covers a range from 1.40129846432481707e-45 to 3.40282346638528860e+38 (positive or negative).

Zoals je ziet is float intern even groot dan integer, maar heeft het wel een veel groter bereik. Dat gaat ten koste van accuraatheid. Niet elk mogelijk getal in dat bereikt kan worden weergegeven.

Indien je exact wilt werken met floating points moet je ofwel je berekeninge zo doen dat ze met integers werken (in uw geval gewoon elk getal*10 doen en als integer definiëren, en dan later door 10 delen), ofwel werken met hulpklassen zoals BigDecimal, standaard in Java aanwezig. Daar zit geen verlies op.

Recipe4hate

Legacy Member
Zou je niet gewoon kunnen optellen en afronden naar x-aantal kommagetallen? String.format() moet je maar eens opzoeken.

SMa

Legacy Member
Een byte gebruiken en tellen tot 70 en telkens 1 bijtellen?
Als je de waarde ergens nodig hebt kun je gewoon delen door 10.

FroFro

Legacy Member
SMa zei:
Een byte gebruiken en tellen tot 70 en telkens 1 bijtellen?
Als je de waarde ergens nodig hebt kun je gewoon delen door 10.

das niet zo handig aangezien ik altijd t moet berekenen, die in een formule plotten, t moet herberekenen, plotten, etc etc :) Maar bedankt!

die String.format() zie ik ni meteen hoe ik die moet gebruike..

Tyfius

Legacy Member
Dit artikel is orgineel voor C++, maar het principe en het idee is hetzelfde in elke taal.

killgore

Legacy Member
FroFro zei:
das niet zo handig aangezien ik altijd t moet berekenen, die in een formule plotten, t moet herberekenen, plotten, etc etc :) Maar bedankt!

die String.format() zie ik ni meteen hoe ik die moet gebruike..

jama, da lijkt voor een functieplotter :p?

Daar doet die 0,0000000x afwijken er niet toe hoor :p. Hoogstens voor je weergave op assen, maar dan doe je idd via formatting dat je maar tot x getallen na de komma weergeeft.

Albireo

Legacy Member
voor wat extra fun met floats, voer deze code eens uit (code in C#)

Code:
         double a = 2 + 0.2 + 0.2 + 0.2 + 0.2 + 0.2 - 3;
         double b = 0.2 + 0.2 + 0.2 + 0.2 + 0.2 + 2 - 3;
         if (a == b) {
                  Console.WriteLine("my CPU rules");
         }
         else {
                  Console.WriteLine("oops");
         }
         Console.WriteLine("2 + 0.2 + 0.2 + 0.2 + 0.2 + 0.2 - 3 = " + a.ToString());
         Console.WriteLine("0.2 + 0.2 + 0.2 + 0.2 + 0.2 + 2 - 3 = " + b.ToString());

Het resultaat op een motorola 68000 CPU is hetzelfde als op een Intel Core 2 Duo E6600 btw

:crazy:

edit: het resultaat als je een float zou gebruiken is eigenlijk nog verrassender. Ik ken dit voorbeeldje al zo'n 15 jaar en nu pas denk ik er aan om het eens met een float uit te testen. :lol:

SMa

Legacy Member
Albireo zei:
voor wat extra fun met floats, voer deze code eens uit (code in C#)

Code:
         double a = 2 + 0.2 + 0.2 + 0.2 + 0.2 + 0.2 - 3;
         double b = 0.2 + 0.2 + 0.2 + 0.2 + 0.2 + 2 - 3;
         if (a == b) {
                  Console.WriteLine("my CPU rules");
         }
         else {
                  Console.WriteLine("oops");
         }
         Console.WriteLine("2 + 0.2 + 0.2 + 0.2 + 0.2 + 0.2 - 3 = " + a.ToString());
         Console.WriteLine("0.2 + 0.2 + 0.2 + 0.2 + 0.2 + 2 - 3 = " + b.ToString());

Het resultaat op een motorola 68000 CPU is hetzelfde als op een Intel Core 2 Duo E6600 btw

:crazy:
Imo wijkt dat niet zo overdreven veel af van elkaar...
Al zou het natuurlijk gewoon gelijk moeten zijn ;)

Resultaat:
2 + 0.2 + 0.2 + 0.2 + 0.2 + 0.2 - 3 = 8,88178419700125E-16
0.2 + 0.2 + 0.2 + 0.2 + 0.2 + 2 - 3 = 0

Albireo

Legacy Member
Waarom steken ze (AMD/Intel) eigenlijk geen BCD-coprocessor (of zoiets) in hun CPU's? Te moeilijk? Te duur? De moeite niet waard?

killgore

Legacy Member
Albireo zei:
Waarom steken ze (AMD/Intel) eigenlijk geen BCD-coprocessor (of zoiets) in hun CPU's? Te moeilijk? Te duur? De moeite niet waard?

BCD = binary coded decimal. Kan je toch perfect 'simuleren' op hun processor?
Allé, ik zie niet in waarom je naast de gewone int-ALU en eventueel SSE-ALU (alle, SSE instructieset) nog een specifieke BCD alu zou moeten hebben, dat kan je toch veel beter softwarematig doen op dezelfde processor.
Het enige dat een beetje lastig is misschien zijn de carries, wat dan mssch iets beter kan gedaan worden hardwarematig (en zelfs dan nog).
Maar het sop zal hier zeker de kolen niet waard zijn. Hoeveel toepasisngen hebben echt getallen nodig die niet door een precisiebereik van 64 bits kunnen worden voorgesteld :x? Zelfs voor het gros van de projecten op projecteuler.net heb ik nog geen bignumber library gebruikt.
Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.
Terug
Bovenaan