Преобразование числа с плавающей точкой или отрицательного целого числа в шестнадцатеричное в Borland Delphi - PullRequest
1 голос
/ 04 февраля 2010

Я написал программу, которая взаимодействует с некоторым оборудованием, используя последовательное соединение. Он отправляет мне много шестнадцатеричных значений (показания датчика) и время от времени отправляет отрицательное значение. ех. я получаю шестнадцатеричное значение: FFFFF5D6 и я должен преобразовать его в: -2602

Еще одна проблема у меня заключается в том, что я не могу преобразовать число с плавающей точкой в ​​гекс и обратно.

Есть ли простые способы сделать это?

Ответы [ 4 ]

2 голосов
/ 05 февраля 2010

Вы можете "преобразовать" из шестнадцатеричного числа в число с плавающей точкой, используя целое число, достаточно большое, чтобы охватить используемое значение с плавающей точкой, а затем использовать ключевое слово ABSOLUTE. Все, что на самом деле делает, это кодирует память значения как целое число. Будьте очень осторожны, чтобы использовать типы одинакового размера (вы можете использовать SIZEOF, чтобы найти объем памяти значения). Если вам нужен нечетный размер, то абсолютный по отношению к массиву байтов и циклический и преобразовать в / из каждого байта (который будет шестнадцатеричный двух символов).

Ключевое слово ABSOLUTE заставляет две переменные запускаться по одному и тому же адресу памяти, любое значение, записанное из одной, сразу же доступно в другой.

var
  fDecimal : Double; // size = 8 bytes
  fInteger : Int64 absolute fDecimal;  // size = 8 bytes
begin
  fDecimal := 3.14;
  ShowMessage(format('%x=%f',[fInteger,fDecimal]));
  fInteger := StrToInt64('$1234123412341234');
  ShowMessage(FloatToStr(fDecimal)+'='+Format('%x',[fInteger]));
end;

вот процедура для поплавков с нечетными размерами:

var
  fDecimal : extended;
  fInteger : array[1..10] of byte absolute fDecimal;
  sHex     : string;
  iX       : integer;
begin
  ShowMessage(IntToStr(SizeOf(fDecimal))+':'+IntToStr(SizeOf(fInteger)));
  fDecimal := 3.14;
  sHex := '';
  for iX := 1 to 10 do
    sHex := sHex + IntToHex(fInteger[iX],2);
  ShowMessage(sHex);
  // clear the value
  fDecimal := 0.0;
  // Reload the value
  for iX := 1 to (Length(sHex) DIV 2) do
    fInteger[iX] := StrToInt('$'+Copy(sHex,(Ix*2)-1,2));
  ShowMessage(FloatToStr(fDecimal));
end;
1 голос
/ 04 февраля 2010

для преобразования шестнадцатеричной строки в целое число, вы можете использовать функцию StrToInt , также вы можете проверить функцию TryStrToInt (которая возвращает False, если строка не представляет действительное число).

uses
SysUtils;

var
ivalue : integer;
begin
ivalue:=StrToInt('$FFFFF5D6'); // Hexadecimal values start with a '$' in Delphi

..
end;

Для шестнадцатеричного представления числа с плавающей запятой вы можете проверить эти статьи.

0 голосов
/ 12 февраля 2018

Если вы хотите разделить показатель степени и значение, вы можете использовать вариант записи:

  TExtRec = packed record
    case Boolean of
      false:
        (AValue: Extended);
      true:
        (ASignificand: uint64; ASignExp: uint16;)
  end;

Я думаю, что это помогает понять структуру числа с плавающей запятой.

Пример использования:

var
  r: TExtRec;
begin
  r.AValue := 123.567;
  ShowMessage(IntToHex(r.ASignExp) + IntToHex(r.ASignificand));
end;

Выход:

 4005F7224DD2F1A9FBE7

Вы можете рассчитать его обратно :

v = (-1)s * 2(e-16383) * (i.f)

С

  • e = $4005 = 16389 и
  • i.f = $F7224DD2F1A9FBE7
  • i.f = 1.930734374999999999954029827886614611998084001243114471435546875
  • v=123.566999999999999997057908984743335167877376079559326171875

Для преобразования i.f я использовал двоичный преобразователь .

0 голосов
/ 04 февраля 2010

Я никогда не видел число с плавающей точкой, представленное в шестнадцатеричном формате, поэтому вам нужно было бы точно определить, какой формат для этого использует устройство. В случае отрицательного числа вам нужно использовать HexToInt, чтобы преобразовать его в целое число, а затем определить, больше ли это целое число, чем любое пороговое значение, представляющее MaxInt для целочисленного типа данных аппаратного обеспечения. Если оно больше этого, это отрицательное число, что означает, что вам нужно, IIRC, получить дополнение числа 1 и преобразовать его в отрицательное.

...