AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Prism Migration nach .NET: Bit-Operatoren und Double
Thema durchsuchen
Ansicht
Themen-Optionen

Migration nach .NET: Bit-Operatoren und Double

Ein Thema von dkoehler · begonnen am 2. Nov 2007 · letzter Beitrag vom 2. Nov 2007
Antwort Antwort
dkoehler

Registriert seit: 1. Nov 2007
33 Beiträge
 
#1

Migration nach .NET: Bit-Operatoren und Double

  Alt 2. Nov 2007, 17:44
Ich möchte folgenden Code von Delphi für Win32 nach Delphi für .NET portiern:
Delphi-Quellcode:
function IsNegZero(const AValue: Double): Boolean;
begin
  Result := PInt64(@AValue)^ = $8000000000000000;
end;

function IsPosZero(const AValue: Double): Boolean;
begin
  Result := PInt64(@AValue)^ = $0000000000000000;
end;
Der Code muß geändert werden, weil ja die Pointer-Zauberei nun in Delphi für .NET nicht mehr funktioniert. Was das ganze außerdem noch schwer macht ist die Tatsache, daß Double in der Delphi-Hilfe nicht extra dokumentiert ist.

a) Weiß jemand, ob Double unter .NET sich genauso verhält wie unter Win32 in bezug auf das Vorzeichen, d.h. daß zumindest intern zwischen positiver und negativer Null unterschieden wird?

b) Weiß jemand, wie man das abfragen kann? Ich habe es mit Bit-Operatoren versucht, aber erhalte z.B. in der Zeile:
Result := (AValue and $8000000000000000) = $8000000000000000; die Fehlermeldung: "Operator not applicable to this operand type" bezüglich AND.
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.171 Beiträge
 
Delphi 10.4 Sydney
 
#2

Re: Migration nach .NET: Bit-Operatoren und Double

  Alt 2. Nov 2007, 17:53
Unter .NET würde ich kein solches Bit-Gefummele mehr machen und einfach per

Delphi-Quellcode:
function IsNegZero(const AValue: Double): Boolean;
begin
  result := (AValue <= 0);
end;

function IsPosZero(const AValue: Double): Boolean;
begin
  Result := (AValue >= 0);
end;
Dann noch noch nach jeder Funktion ein inline ergänzt und der Code dürfte schneller sein als dein alter Code da er einen Funktionscall einspart.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
Hawkeye219

Registriert seit: 18. Feb 2006
Ort: Stolberg
2.227 Beiträge
 
Delphi 2010 Professional
 
#3

Re: Migration nach .NET: Bit-Operatoren und Double

  Alt 2. Nov 2007, 18:08
Hallo Bernhard,

ich glaube, hier soll auf die positive und negative Null getestet werden.

Gruß Hawkeye
  Mit Zitat antworten Zitat
dkoehler

Registriert seit: 1. Nov 2007
33 Beiträge
 
#4

Re: Migration nach .NET: Bit-Operatoren und Double

  Alt 2. Nov 2007, 18:16
Zitat von Bernhard Geyer:
Unter .NET würde ich kein solches Bit-Gefummele mehr machen und einfach per

Delphi-Quellcode:
function IsNegZero(const AValue: Double): Boolean;
begin
  result := (AValue <= 0);
end;

function IsPosZero(const AValue: Double): Boolean;
begin
  Result := (AValue >= 0);
end;
Dieser Code funktioniert nicht, weil die Vergleichsoperatoren eben nicht zwischen positiver und negativer Null unterscheiden (siehe IEEE 754).
  Mit Zitat antworten Zitat
Benutzerbild von Christian S.
Christian S.

Registriert seit: 19. Apr 2003
Ort: Düsseldorf
835 Beiträge
 
#5

Re: Migration nach .NET: Bit-Operatoren und Double

  Alt 2. Nov 2007, 18:22
Die BitConverter.DoubleToInt64Bits-Methode könnte Dir helfen, die Bits zu verlgeichen.
Christian S.
Admin in der Entwickler-Ecke
  Mit Zitat antworten Zitat
Dax
(Gast)

n/a Beiträge
 
#6

Re: Migration nach .NET: Bit-Operatoren und Double

  Alt 2. Nov 2007, 18:27
Falls du nicht den unsafe-Code-Umweg, den Christian vorschlägt, gehen willst, könnte folgendes funktionieren. Ich hoffe, Delphi untersützt sowas, ansonsten nutze direkt den C#-Code (falls er denn funktioniert)
Code:
using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Explicit)]
struct DoubleInt64Union
{
  [FieldOffset(0)]
  public readonly double Double;
  [FieldOffset(0)]
  public readonly long Int64;

  public DoubleInt64Union(double d)
  {
    this.Double = d;
  }

  // Zum Vergleich, das BitConverter-Teil
  public static unsafe long DoubleToInt64Bits(double value)
  {
    return *((long*)&value); // <- das hast du in Delphi auch getan
  }
}
Das ist im Prinzip das selbe wie variante Records in Delphi, und du kannst wie gehabt das Int64-Feld mit deinem $(0|8)0* vergleichen.
  Mit Zitat antworten Zitat
dkoehler

Registriert seit: 1. Nov 2007
33 Beiträge
 
#7

Re: Migration nach .NET: Bit-Operatoren und Double

  Alt 2. Nov 2007, 19:12
Danke für die Hilfe! Ich habe gemäß Christians Vorschlags, BitConverter.DoubleToInt64Bits benutzt. Offenbar ist der entgegen Dax' Bedenken doch "safe". Jedenfalls beschwert sich der Compiler nicht. Hier mein Code (noch ungetestet):

Delphi-Quellcode:
function IsNegZero(const AValue: Double): Boolean;
var
  D: Int64;
begin
  D := BitConverter.DoubleToInt64Bits(AValue);
  Result := D = $8000000000000000;
end;

function IsPosZero(const AValue: Double): Boolean;
var
  D: Int64;
begin
  D := BitConverter.DoubleToInt64Bits(AValue);
  Result := D = $0000000000000000;
end;
  Mit Zitat antworten Zitat
Dax
(Gast)

n/a Beiträge
 
#8

Re: Migration nach .NET: Bit-Operatoren und Double

  Alt 2. Nov 2007, 19:19
"Unsafe Code" bedeutet auch nur, dass die Runtime in der Methode an manchem Stellen mit nicht verwaltetem Speicher arbeitet - sprich: Zeigern - also Speicher, von dem sie nie weiß, wann er gültig ist und wann er ungültig wird. Daraus folgt, dass die Zeiger nicht durch den GC gejagt werden und bei falschem rumgezeigere tatsächlich Speicherlecks entstehen. In den BitConverter-Methoden ist das natürlich nicht der Fall, da kein Speicher alloziert wird, daher sind diese wirklich gewissermaßen "safe".
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.171 Beiträge
 
Delphi 10.4 Sydney
 
#9

Re: Migration nach .NET: Bit-Operatoren und Double

  Alt 2. Nov 2007, 21:51
Zitat von dkoehler:
Dieser Code funktioniert nicht, weil die Vergleichsoperatoren eben nicht zwischen positiver und negativer Null unterscheiden (siehe IEEE 754).
Also manchmal sollte man doch genauer lesen was der Fragesteller wollte
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
Antwort Antwort


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 00:47 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