PB kann nicht rechnen!

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
Zaphod
Beiträge: 2875
Registriert: 29.08.2004 00:40

Beitrag von Zaphod »

ich verstehe nicht wo das problem liegt. wenn du round sagst das es aufrunden soll, dann rundet es auf.

60.00000000004 ist eben größer als 60.0 und wird, wenn du round sagst es soll aufrunden aufgerundet.

round ist dafür gut, wofür es gedacht ist. zum thema gleitkomma ungenauigkeit muß man eigentlich auch nichts mehr sagen. ich empfehle das studium dieser beiden links:

was ist approximation:
http://de.wikipedia.org/wiki/Approximation

ist die gleitkomma darstellung eventuel approximativ?:
http://de.wikipedia.org/wiki/Flie%C3%9Fkomma-Zahlen
Gimbly
Beiträge: 169
Registriert: 28.12.2005 14:26
Wohnort: NRW

Beitrag von Gimbly »

Klar kann der arme round-Befehl 60.000004 nur zu 61 aufrunden, aber er darf nicht 100 * 0.6 zu 61 aufrunden.

Der Bug besteht natürlich dadrin, dass 100 * 0.6 falsch gerechnet wird.

Das kenne ich aus C und Delphi anders.
Gruß
Markus
Benutzeravatar
Ypser
XMas-Contest-Gewinner '03
Beiträge: 128
Registriert: 29.08.2004 14:35
Computerausstattung: Win7
Wohnort: Ingelheim
Kontaktdaten:

Beitrag von Ypser »

Vielleicht sollte Fred, wie in anderen Programmiersprachen auch, für solche Dinge die Befehle
Floor() und Ceil() einführen, und dafür Round() endlich zu einem intelligenten Befehl machen. :?

Stümperversion:

Code: Alles auswählen

Procedure Round_Intelligent(v.f)
  nc.f = (v - Int(v))
  If (nc >= 0.5)
    pr.l = Int(v + 1)
  Else
   pr.l = Int(v)
  EndIf
  Procedurereturn pr
EndProcedure
Bild
Benutzeravatar
Zaphod
Beiträge: 2875
Registriert: 29.08.2004 00:40

Beitrag von Zaphod »

c und delphi haben das selbe problem. das ist nämlich keine eigenschaft der programmiersprache sondern der floating point unit. in c und delphi hat man allerdings doubles, bei denen die approximation natürlich besser funktioniert.
Benutzeravatar
Batze
Beiträge: 1492
Registriert: 03.06.2005 21:58
Wohnort: Berlin
Kontaktdaten:

Beitrag von Batze »

Gimbly hat geschrieben: Der Bug besteht natürlich dadrin, dass 100 * 0.6 falsch gerechnet wird.
Um genau zu sein gibt es den Wert 0.6 im Binären Floats garnicht.
Das ist doch im Dezimalsystem genauso.

30 * 0.333333333 ist doch auch nicht genau 10.
0.6 ist im Binärsystem ebenfalls eine Ungenaue Zahl.

Aber ließ dir die Links durch. :freak:
Hier sind meine Codes (aber die Seite geht gerade nicht):
http://www.basicpure.de.vu
Benutzeravatar
Froggerprogger
Badmin
Beiträge: 855
Registriert: 08.09.2004 20:02

Beitrag von Froggerprogger »

Der Bug besteht natürlich dadrin, dass 100 * 0.6 falsch gerechnet wird.
Das kenne ich aus C und Delphi anders.
Hier ein äquivalenter C-Code und ein Java-Code:

Code: Alles auswählen

#include <stdio.h>
#include <math.h>

int main(void) {
	float 	f;
	int 	i;
	
	f = 100.0f * 0.6f;
	
	printf("%f\n",f);
	printf("%f", ceil(f));
}

Code: Alles auswählen

public class RoundTest {
	public static void main (String [] args) {
		float f = 100.0f * 0.6f;
		System.out.println(f);
		System.out.println(Math.ceil(f));		
	}	
}
Beide liefern als Ergebnis:

60.000004
61.000000

Lässt man das 'f' hinter dem Zahlenliteral weg, wird es als ein double-Literal interpretiert, daher dann in C auch mit doubles gerechnet und anschließend implizit nach float gecastet, wodurch das Ergebnis scheinbar richtig wird, da die Ungenauigkeit dann außerhalb der von floats liegt. Bei Java wird beim weglassen der 'f' eine cast-exception geworfen, da man explizit von double auf float downcasten muss, um diesen Effekt nur bewußt einzusetzen.

In Delphi wird es dasselbe sein. Das ist kein PB-Bug, sondern eine Ungenauigkeit bei floats.
!UD2
MARTIN
Beiträge: 454
Registriert: 08.09.2004 14:03
Wohnort: Kiel

Beitrag von MARTIN »

Ja, eben.
Eine float Variable kann einfach nicht genau den Wert 0.6 annehmen, sodern nur einen Wert um 0.6.
In C gibt es dieses Problem genau so:

Code: Alles auswählen

printf("%.12f\n",100.0F*0.6F);
Zeigt :60.000003814697

So jetzt wurde es 10mal gesagt.

/*Edit :Eigentlich habe ich mein Beitrag schon gegen 12.15 gepostet vor dem Beitrag von Batze*/
Zuletzt geändert von MARTIN am 27.01.2006 13:13, insgesamt 3-mal geändert.
Amilo 1667|Suse Linux 10.1_64bit/WinXP |PB 4.00/3.94
Benutzeravatar
Batze
Beiträge: 1492
Registriert: 03.06.2005 21:58
Wohnort: Berlin
Kontaktdaten:

Beitrag von Batze »

Es ist zwecklos das jedes mal wieder zu erklären.
Am besten irgendwer erklärrt das mal in einem Thread der dann in Anfänger als besonders wichtig markiert ist.
Hier sind meine Codes (aber die Seite geht gerade nicht):
http://www.basicpure.de.vu
Benutzeravatar
Froggerprogger
Badmin
Beiträge: 855
Registriert: 08.09.2004 20:02

Beitrag von Froggerprogger »

Man könnte auch die RTFM-Keule schwingen:
Aus der Hilfe zu "Variablen, Typen und Operatoren"
Spezielle Informationen über Fließkommazahlen (Floats)

Eine Fließkomma-Zahl (auch Gleitkomma-Zahl, englisch: Floating Point Number) wird in einer Art und Weise gespeichert, die den Binär-Punkt (trennt "Ganzzahlteil" vom "Kommateil") innerhalb der Zahl "gleiten" lässt, wodurch das Speichern sehr großer aber auch sehr kleiner Zahlen (mit vielen Nachkommastellen) möglich wird. Wie auch immer, Sie können nicht sehr große Zahlen mit gleichzeitig sehr hoher Genauigkeit (sozusagen große und kleine Zahlen zur selben Zeit) speichern. Eine weitere Einschränkung von Fließkomma-Zahlen ist, dass sie stets im Binärmodus arbeiten, weshalb sie nur die Zahlen exakt speichern können, welche mittels Multiplikation oder Division mit 2 ermittelt werden können. Dies ist insbesondere wichtig zu wissen, wenn Sie versuchen, eine Fließkommazahl in einer visuell lesbaren Form darzustellen (oder mit ihr Rechenoperationen auszuführen) - das Speichern von Zahlen wie 0.5 oder 0.125 ist einfach, da sie Divisionen von 2 sind. Das Speichern von Zahlen wie 0.1 ist schwieriger, diese wird möglicherweise als Zahl 0.9996125 gespeichert. Sie können versuchen, nur eine begrenzte Anzahl an (Nachkomma-) Stellen darzustellen, seien Sie aber nicht überrascht, wenn die Darstellung der Zahl anders aussieht, als Sie dies erwarten!

Dies gilt für alle Fließkomma-Zahlen, nicht nur die in PureBasic.
!UD2
Benutzeravatar
Falko
Admin
Beiträge: 3535
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.11b1
HP255G8 Notebook @AMD Ryzen 5 5500U with Radeon Graphics 2.10 GHz 3.4GHz, 32GB_RAM, 3TB_SSD (Win11 Pro 64-Bit)
Kontaktdaten:

Beitrag von Falko »

Wenn jemand Lust hat, dieses in PB umzusezten, dann kehrt Ruhe ein :mrgreen:

http://vb-tec.de/runden.htm
Bild
Win11 Pro 64-Bit, PB_6.11b1
Antworten