AW: Power funktioniert nicht wie gedacht
Zitat:
|
AW: Power funktioniert nicht wie gedacht
So sieht mein Versuch aus. Alles was über 1 TiB hinaus geht, kann ich verwerfen.
Delphi-Quellcode:
CalculateSize übergebe ich beispielsweise 305 und 2 übergebe, bekomme ich als Ergebnis 305 MiB.
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; Alles was über 1 TiB geht wird verworfen. Das macht genau das was ich brauche. |
AW: Power funktioniert nicht wie gedacht
Ich frage jetzt zu letzen Mal: Warum kannst Du kein Double oder Extended verwenden?
Delphi-Quellcode:
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.
function CalculateSize(Bytes, Multiplier: Int64): Double;
|
AW: Power funktioniert nicht wie gedacht
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. |
AW: Power funktioniert nicht wie gedacht
Zitat:
Da ja auch Buchstaben in TEdit möglich sind ... : https://www.delphipraxis.net/19039-e...rlauben-2.html |
AW: Power funktioniert nicht wie gedacht
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:
Einen Integer-Overflow sollte es eigentlich wegen
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;
Delphi-Quellcode:
nicht geben.
if dTmp > MaxSize then dTmp := MaxSize;
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. |
AW: Power funktioniert nicht wie gedacht
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; |
AW: Power funktioniert nicht wie gedacht
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; |
AW: Power funktioniert nicht wie gedacht
Zitat:
|
AW: Power funktioniert nicht wie gedacht
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 |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:14 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