AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Power funktioniert nicht wie gedacht

Ein Thema von DieDolly · begonnen am 24. Jul 2018 · letzter Beitrag vom 25. Jul 2018
Antwort Antwort
Seite 3 von 5     123 45      
gammatester

Registriert seit: 6. Dez 2005
999 Beiträge
 
#21

AW: Power funktioniert nicht wie gedacht

  Alt 24. Jul 2018, 22:45
Vielleicht helfe ich euch und auch mir, wenn ich mein Problem erkläre.
Ich habe ein TEdit sowie eine TComboBox. Im Edit kann ich eine Zahl eingeben und in der ComboBox kann ich von Byte bis Gigabyte alles auswählen.
Die eingegebene Zahl soll später in das umgerechnet werden, was ich in der ComboBox ausgewählt habe. Das schaffe ich. Aber wie außer mit try except fange ich Fehleingaben ab, sodass die Zahl niemals größer wird als 1099511627775 Bytes (1TB-1Byte)
Punkt1: Wieso kannst Du kein Double oder Extended nehmen? Punkt 2: Wie schon mehrfach vorgerechnet, passen 70 Bits weder in ein 64-Bit-Integer, noch ohne ein paar Bit Genauigkeitsverlust in ein Fließkomma mit 53- oder 64-Bit Mantisse. Du könntest natürlich Multi-Präzisions-Integer verwenden, aber ich halte das für Overkill.
  Mit Zitat antworten Zitat
DieDolly

Registriert seit: 22. Jun 2018
2.175 Beiträge
 
#22

AW: Power funktioniert nicht wie gedacht

  Alt 24. Jul 2018, 23:01
So sieht mein Versuch aus. Alles was über 1 TiB hinaus geht, kann ich verwerfen.

Delphi-Quellcode:
function CalculateSize(Bytes, Multiplier: Int64): UInt64;
const
 MaxSize: Int64 = 1099511627776; // 1 TiB
var
 dTmp: Double;
begin
 if Multiplier > 0 then
  dTmp := System.Math.Power(1024, Multiplier)
 else
  dTmp := 1;

 dTmp := Bytes * dTmp;

 if dTmp > MaxSize then
  dTmp := MaxSize;

 Result := Round(dTmp); // Round um von Double auf Int64 zu kommen [ob Round oder Trunc ist ja egal]
end;
CalculateSize übergebe ich beispielsweise 305 und 2 übergebe, bekomme ich als Ergebnis 305 MiB.
Alles was über 1 TiB geht wird verworfen.

Das macht genau das was ich brauche.
  Mit Zitat antworten Zitat
gammatester

Registriert seit: 6. Dez 2005
999 Beiträge
 
#23

AW: Power funktioniert nicht wie gedacht

  Alt 24. Jul 2018, 23:09
Ich frage jetzt zu letzen Mal: Warum kannst Du kein Double oder Extended verwenden? function CalculateSize(Bytes, Multiplier: Int64): Double; Die Genauigkeit hast Du eh schon verloren, Du hast als Ergebnis ja max 53 signifikante Mantissa-Bits, es geht jetzt nur noch darum, keinen Integer-Overflow zu erhalten.

Geändert von gammatester (24. Jul 2018 um 23:13 Uhr)
  Mit Zitat antworten Zitat
DieDolly

Registriert seit: 22. Jun 2018
2.175 Beiträge
 
#24

AW: Power funktioniert nicht wie gedacht

  Alt 24. Jul 2018, 23:16
Weil die Funktion der ich das Ergebnis übergebe Int64 erwartet.
Das Ergebnis darf maximal so groß sein wie die maximale Dateigröße unter NTFS. Also 16 TiB.
  Mit Zitat antworten Zitat
THY4243

Registriert seit: 15. Dez 2012
Ort: München - Untermenzing
44 Beiträge
 
Delphi 11 Alexandria
 
#25

AW: Power funktioniert nicht wie gedacht

  Alt 24. Jul 2018, 23:22
Vielleicht helfe ich euch und auch mir, wenn ich mein Problem erkläre.
Ich habe ein TEdit sowie eine TComboBox. Im Edit kann ich eine Zahl eingeben und in der ComboBox kann ich von Byte bis Gigabyte alles auswählen.
Die eingegebene Zahl soll später in das umgerechnet werden, was ich in der ComboBox ausgewählt habe. Das schaffe ich. Aber wie außer mit try except fange ich Fehleingaben ab, sodass die Zahl niemals größer wird als 1099511627775 Bytes (1TB-1Byte)
Deine Erklärung geht in eine zweite Richtung (neben dem mathemat. Thema)? Wenn es um das "Abfangen" geht, müsstest Du nach jedem Tastendruck das TEdit-Feld auswerten und auf Gültigkeit in Deinem Sinn berechnen. Das würde mittels der Ereignisse des TEdit gehen.
Da ja auch Buchstaben in TEdit möglich sind ... : https://www.delphipraxis.net/19039-e...rlauben-2.html
  Mit Zitat antworten Zitat
DieDolly

Registriert seit: 22. Jun 2018
2.175 Beiträge
 
#26

AW: Power funktioniert nicht wie gedacht

  Alt 24. Jul 2018, 23:27
Ich habe meine Funktion jetzt angepasst. Maximaledateigröße 16 EiB minus 1 KiB. Laut Wikipedia die größte zulässige Dateigröße unter NTFS.
Die Funktion funktioniert soweit ganz gut und macht genau was ich brauche.

Delphi-Quellcode:
function CalculateSize(Bytes, Multiplier: UInt64): UInt64;
const
 MaxSize: UInt64 = 18446744073709551615 - 1024; // 16 EiB - 1 KiB
var
 dTmp: Double;
begin
 if Multiplier > 0 then
  dTmp := System.Math.Power(1024, Multiplier)
 else
  dTmp := 1;

 dTmp := Bytes * dTmp;

 if dTmp > MaxSize then
  dTmp := MaxSize;

 Result := Trunc(dTmp);
end;
Einen Integer-Overflow sollte es eigentlich wegen if dTmp > MaxSize then dTmp := MaxSize; nicht geben.
Statt Round, was Int64 erwartet, nehme ich jetzt Trunc. Damit sollte alles normalisiert werden.

Ok einen Overflow bekomme ich mit Round und Trunc trotzdem noch wenn dTmp = Maxsize ist.

Wenn ich MaxSize auf 1152921504606847000 (1 EiB) verkleinere, ist das Problem erledigt.
So lasse ich das jetzt auch. Denn ich denke niemand wird jemals eine Datei >1 EiB erzeugen. Und wenn, dann sind es Aliens.

Geändert von DieDolly (24. Jul 2018 um 23:57 Uhr)
  Mit Zitat antworten Zitat
Michael II

Registriert seit: 1. Dez 2012
Ort: CH BE Eriswil
760 Beiträge
 
Delphi 11 Alexandria
 
#27

AW: Power funktioniert nicht wie gedacht

  Alt 25. Jul 2018, 01:53
Nicht gut: Durch Umwandlung von uint64 zu double und zurück zu uint64 verlierst du bei grossen Zahlen an Präzision.

Grund: double ist nur auf ca. 15 Stellen (dezimal) präzis während uint64 Werte 19 stellig sein können.

http://docwiki.embarcadero.com/RADStudio/Tokyo/de/Interne_Datenformate_(Delphi)


Beispiele:
9000000000000000512 wird durch Umwandlung in double und zurück zu uint64 zu
9000000000000000000

9000000000000000513 wird zu 9000000000000001024


Wenn du mit uint64 Genauigkeit rechnen willst, dann verzichte auf double.

Deine uint64 Power Funktion könnte so aussehen:

Delphi-Quellcode:
function Power( exp : integer ) : uint64;
begin
  Result := uint64(1) shl (exp*10); // exp in [0..6] check einbauen
end;
Michael Gasser
  Mit Zitat antworten Zitat
DieDolly

Registriert seit: 22. Jun 2018
2.175 Beiträge
 
#28

AW: Power funktioniert nicht wie gedacht

  Alt 25. Jul 2018, 02:09
Das funktioniert perfekt!

Delphi-Quellcode:
function ConvertBytes(Bytes: UInt64; Multiplier: Integer): UInt64;
const
 // When the calculated filesize is bigger than MaxSize, than normalise it to MaxSize.
 // I think nobody (not a "normal" person) would ever create a file bigger than 1 EiB
 MaxSize: UInt64 = 1152921504606847000; // 1 EiB
begin
 if Multiplier> 0 then
  Result := UInt64(1) shl (Multiplier* 10)
 else
  Multiplier:= 1;

 Result := Bytes * Result;

 if Result > MaxSize then
  Result := MaxSize;
end;

Geändert von DieDolly (25. Jul 2018 um 02:13 Uhr)
  Mit Zitat antworten Zitat
madas

Registriert seit: 9. Aug 2007
207 Beiträge
 
#29

AW: Power funktioniert nicht wie gedacht

  Alt 25. Jul 2018, 07:07
Ich möchte gerne Byte in MB, GB usw umrechnen.
Wenn Du Byte in MB bzw. GB umrechnen möchtest, dann frage ich mich, warum Du mit "*" bzw. Potenzen rechnest.
  Mit Zitat antworten Zitat
TigerLilly

Registriert seit: 24. Mai 2017
Ort: Wien, Österreich
1.205 Beiträge
 
Delphi 11 Alexandria
 
#30

AW: Power funktioniert nicht wie gedacht

  Alt 25. Jul 2018, 07:12
Der Thread ist ein gutes Beispiel für "Wie löse ich anstelle meines Problems eines, das es gar nicht gibt, und zwar so, dass es keiner versteht?".

Das zu lösende Problem ist doch, dass es "rundherum" Beschränkungen in den erwarteten Typen gibt. Das sollte gelöst werden.
Wenn das - warum auch immer - nicht geht, dann ist die Aufgabenstellung sinnvoll zu lösen und das Ergebnis auf die Typen brauchbar abzubilden.

Jetzt gibt es eine Lösung, die MaxSize zurückliefert, auch wenn der richtige Wert > MaxSize wäre. Gar nicht gut.

if Multiplier> 0 then
Result := UInt64(1) shl (Multiplier* 10) // Das versteht keiner auf den ersten Blick.
else
Multiplier:= 1; // Das ist Irreführung - wird ja gar nicht mehr verwendet.

Result := Bytes * Result; // Welchen Wert hat Result, wenn Multiplyer 0 ist?

if Result > MaxSize then
Result := MaxSize; // das tut in der Seele weh
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 5     123 45      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:12 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz