Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi JSON UInt64 convert error QP (https://www.delphipraxis.net/213476-json-uint64-convert-error-qp.html)

KodeZwerg 4. Aug 2023 02:48


JSON UInt64 convert error QP
 
Hallo, ich wusste nicht wirklich in welche Sparte ich das Schreiben müßte deswegen ist es hier gelandet, bitte verschieben falls es hier fehl am Platz ist.
Es geht um Delphi Alexandria und deren JSON Library die nicht im Stande ist UInt64 korrekt zu verarbeiten.
Ich habe RSP-42079 erstellt, damit Ihr voten könnt.

Wer keinen Zugang dort hat, hier ist ein minimal Beispiel um es nachzuvollziehen oder mich im Besten Fall zu korrigieren!
Delphi-Quellcode:
program Project1;
 
uses
  System.JSON;
 
var
  JSonObject: TJSONObject;
begin
  JSonObject := TJSONObject.Create;
  try
    JSonObject.AddPair('Test', TJSONNumber.Create(High(UInt64)));
    WriteLn(JSonObject.GetValue('Test').AsType<UInt64>);
  finally
    JSonObject.Free;
  end;
  ReadLn;
end.

Union 4. Aug 2023 09:39

AW: JSON UInt64 convert error QP
 
Das liegt an der internen Exponentialdarstellung des UInt64 Maxvalue (1.84467440737096E19). Die _Val Funktionen der RTL brechen ab, da dort der Dezimalpunkt nicht als gültiges Zeichen erkannt wird.

Uwe Raabe 4. Aug 2023 09:46

AW: JSON UInt64 convert error QP
 
Als Workaround bietet sich die Umwandlung in einen String vor dem Aufruf des Constructors an:
Delphi-Quellcode:

    JSonObject.AddPair('Test', TJSONNumber.Create(High(UInt64).ToString)); // System.SysUtils in uses ergänzen
Ist der UINT im JSON bereits korrekt codiert, wird er beim Auslesen auch korrekt in eine UINT64 umgewandelt.

himitsu 4. Aug 2023 09:52

AW: JSON UInt64 convert error QP
 
Nja, per se ist das Number im JSON als IEEE 754 double-precision binary floating-point format (binary64) definiert,
bzw. wird von vielen Bibliotheken so implementiert.

Somit hast'e bei Int64/UInt64 eh schnell probleme, da sie nicht in Double passen (19-20 Dezimalstellen, aber effektiv nur 15-16 stehen zur Verfügung)
Auch wenn einige Bibliotheken locker mal 128 Bytes aka Chars (inzwischen 8 KB) für eine Number im Parser zur Verfügung haben (eine Zahl mit tausenden Dezimalstellen)

Letztendlich kommt es natürlich auf die jeweilige Implementation drauf an.
https://www.ibm.com/docs/en/datapowe...-parser-limits
https://gist.github.com/JosePedroDia...0c49212bab644e
...


Tja, notfalls mußt du eben als String speichern und dann selber umwandeln.
Und ansonsten den "Bug" am Emba melden.

Union 4. Aug 2023 09:54

AW: JSON UInt64 convert error QP
 
Leider ist das alles in System.pas und läßt sich nicht einfach korrigieren. Den pragmatischen Vorschlag von Uwe finde ich daher ganz ok.

Stolle58 4. Aug 2023 10:28

AW: JSON UInt64 convert error QP
 
Man könnte sich, aber auch selbst einen class helper schreiben:

Code:
type
  TJSONNumberHelper = class helper for TJSONNumber
  public
    constructor Create(const Value: UInt64); overload;
  end;


{ TJsonNumberHelper }

constructor TJSONNumberHelper .Create(const Value: UInt64);
begin
  inherited Create(Value.ToString);

end;

Uwe Raabe 4. Aug 2023 10:30

AW: JSON UInt64 convert error QP
 
Zitat:

Zitat von himitsu (Beitrag 1525265)
Tja, notfalls mußt du eben als String speichern und dann selber umwandeln.

Delphi-Quellcode:
TJSONNumber.Create(...)
speichert ja den Wert bereits in einem String.

Bei einem UINT64-Parameter ist halt der nächst-passende overload die Double-Version. Das Problem entsteht also schon beim Aufruf von Create und muss also auch dort behoben werden.

Stolle58 4. Aug 2023 10:38

AW: JSON UInt64 convert error QP
 
JSONNumber besitzt mehrere Überladende Constructoren die den Value in einen string konvertiert.

KodeZwerg 4. Aug 2023 12:18

AW: JSON UInt64 convert error QP
 
Vielen Dank Reinhold und Uwe, beides funktioniert einwandfrei!
Für mich selbst nehme ich die Helper Variante um wie gewohnt ohne selbst zu casten das gewünschte Ergebnis zu erhalten.

Da es in meinen Augen ein Bug ist, jede Stimme zählt :)


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:39 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz