#1 2010-08-12 01:11:43

longge007
Member
Registered: 2010-06-22
Posts: 107

how to convert HeXstring to float Data

our httpServer have added new functions ,like dataasHex ,in Ajaxrequest, we can get Hexstr, now i don't know how to convert. thanks a lot.

Offline

#2 2010-08-12 07:24:02

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,182
Website

Re: how to convert HeXstring to float Data

Take a look at server side:

function TSQLRestServerTest.DataAsHex(aRecord: TSQLRecordPeople;
  aParameters: PUTF8Char; const aSentData: RawUTF8; var aResp,
  aHead: RawUTF8): Integer;
(...)
  aResp := JSONEncodeResult([SynCommons.BinToHex(aData)]);

So the conversion to hex is made by SynCommons.BinToHex function.

Just use SynCommons.HexToBin function, like this:

var aResp: RawUTF8;
     Data: array of single;
begin
  aResp := Record.DataAsHex(Client);
  if aResp<>'' then begin
    SetLength(Data,length(aResp) div 8); // single size = 4 bytes, hexadecimal size = 2 chars per byte -> each Data[] item uses 8 hexa chars
    if not SynCommons.HexToBin(pointer(aResp),pointer(Data),length(Data)*4) then
      exit; // error in aResp format (not pure hexadecimal content)
  end;
(...)

Offline

#3 2010-08-12 07:29:28

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,182
Website

Re: how to convert HeXstring to float Data

But if your purpose is to store an array of single/double just for Delphi applications, you don't need to use hex encoding, you can transmit raw binary data with such blob fields, therefore spare some bandwidth.

Then map the array with TRawByteString using SetString(aBlob,) and SetLength(Array,)+move() as I've shown you.

Offline

#4 2010-08-13 02:56:25

longge007
Member
Registered: 2010-06-22
Posts: 107

Re: how to convert HeXstring to float Data

ab wrote:

But if your purpose is to store an array of single/double just for Delphi applications, you don't need to use hex encoding, you can transmit raw binary data with such blob fields, therefore spare some bandwidth.

Then map the array with TRawByteString using SetString(aBlob,) and SetLength(Array,)+move() as I've shown you.

sir:
   i mean how to get Data in WEB pages. for DataasHex function have returned with Hexstirng data. i googled it more,haven't get good method. do you have some about it.

Offline

#5 2010-08-13 06:08:46

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,182
Website

Re: how to convert HeXstring to float Data

Convert from hex to javascript float?
I don't think that's possible, because javascript don't know about singe/double/extended which are x87 FPU values.

In this case, you must transmit your data as JSON.

Offline

#6 2010-08-13 08:03:03

longge007
Member
Registered: 2010-06-22
Posts: 107

Re: how to convert HeXstring to float Data

ab wrote:

Convert from hex to javascript float?
I don't think that's possible, because javascript don't know about singe/double/extended which are x87 FPU values.

In this case, you must transmit your data as JSON.

ok.i will solve it by Server side, i can define onenew function of returning Json string for my Array of single Data.

thanks a lot

Offline

#7 2010-08-13 08:22:17

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,182
Website

Re: how to convert HeXstring to float Data

Take a look at JSONEncode function of SynCommons unit.
This function encodes the data as a JSON object, but I guess you'd prefer a JSON array in your case.
Unlike JSON objects, JSON arrays are enclosed between square braces [ ]. The JSON array is an ordered sequence of values separated by a comma (,). The values can be any of the primitive types as well as the two structures, JSON objects and JSON arrays.

Coding an array of doubles into a corresponding JSON array could be like this (I didn't test this, just coded in the forum here):

function JSONEncodeDouble(const Values: array of double;
  TempMemoryStream: TMemoryStream=nil): RawUTF8;
var A: PtrInt;
    W: TTextWriter;
begin
  if TempMemoryStream<>nil then
    TempMemoryStream.Seek(0,soFromBeginning);
  W := TTextWriter.Create(TempMemoryStream);
  try
    W.Add('[');
    for A := 0 to high(Values) do begin
      W.Add(Values[A],5); // 5 is the number of decimals to be used
      W.Add(',');
    end;
    W.CancelLastComma;
    W.Add(']');
    result := W.Text;
  finally
    W.Free
  end;
end;

Offline

#8 2010-08-13 08:43:55

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,182
Website

Re: how to convert HeXstring to float Data

I've just added these functions in SynCommons.pas:

/// encode the supplied array data as an UTF-8 valid JSON array content
// - the decimals parameter specifies how many decimals must be written (i.e.
// the precision to be used for numerical to text conversion)
// - you can specify a memory stream (for example any TSQLRest.TempMemoryStream)
// to make it faster, since no memory allocation will be processed
function JSONEncodeArray(const Values: array of double; decimals: integer;
  TempMemoryStream: TMemoryStream=nil): RawUTF8; overload;

/// encode the supplied array data as an UTF-8 valid JSON array content
// - you can specify a memory stream (for example any TSQLRest.TempMemoryStream)
// to make it faster, since no memory allocation will be processed
function JSONEncodeArray(const Values: array of RawUTF8;
  TempMemoryStream: TMemoryStream=nil): RawUTF8; overload;

/// encode the supplied array data as an UTF-8 valid JSON array content
// - you can specify a memory stream (for example any TSQLRest.TempMemoryStream)
// to make it faster, since no memory allocation will be processed
function JSONEncodeArray(const Values: array of integer;
  TempMemoryStream: TMemoryStream=nil): RawUTF8; overload;

It could make your work easier, and could serve for other users of the framework.

There was JSONEncode function to be used for creating any JSON object content.
Here are the functions to create JSON array content.

Offline

#9 2010-08-23 06:54:25

longge007
Member
Registered: 2010-06-22
Posts: 107

Re: how to convert HeXstring to float Data

JSONEncodeDouble(const Values: array of double;decimals: integer;..

decimals only can define how many digital number in string.
i think  the formatstring: like '#.00' or '#.##' is very used in JSONEncodeDouble.
if we use decimals. sometimes the Value will be Scientific format.In http webpages it's not wanted.

Offline

#10 2010-08-23 07:06:58

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,182
Website

Re: how to convert HeXstring to float Data

longge007 wrote:

decimals only can define how many digital number in string.
i think  the formatstring: like '#.00' or '#.##' is very used in JSONEncodeDouble.
if we use decimals. sometimes the Value will be Scientific format.In http webpages it's not wanted.

The following function is used:

function ExtendedToString(var S: ShortString; Value: Extended; decimals: integer): integer;
begin
  result := FloatToText(@S[1], Value, fvExtended, ffGeneral, decimals, 0);
end;

So the ffGeneral format is used, which could lead into Scientific format:

Delphi 7 help wrote:

General number format. The value is converted to the shortest possible decimal string using fixed or scientific format. Trailing zeros are removed from the resulting string, and a decimal point appears only if necessary. The resulting string uses fixed point format if the number of digits to the left of the decimal point in the value is less than or equal to the specified precision, and if the value is greater than or equal to 0.00001. Otherwise the resulting string uses scientific format, and the Digits parameter specifies the minimum number of digits in the exponent (between 0 and 4).

Scientific format is well handled in JavaScript, as far as I know.
You have plenty of functions in Javascript Math.
See http://www.actionscript.org/forums/show … eadid=2652 for example about displaying/rounding.

I tried to use ffFixed format instead of ffGeneral:

Delphi 7 help wrote:

Fixed point format. The value is converted to a string of the form "-ddd.ddd...". The resulting string starts with a minus sign if the number is negative, and at least one digit always precedes the decimal point. The number of digits after the decimal point is given by the Digits parameter--it must be between 0 and 18. If the number of digits to the left of the decimal point is greater than the specified precision, the resulting value will use scientific format.

But this ffFixed is not to be used for data transmission. For example -4,560219089e-11 is converted to 0. This could be OK for display or reporting, but it's not correct if you want to transmit data.
So I'll stick to ffGeneral format.

Offline

#11 2010-08-23 10:05:17

longge007
Member
Registered: 2010-06-22
Posts: 107

Re: how to convert HeXstring to float Data

look at my codes Dataashex

function TSQLRestServerWave.DataAsHex(aRecord: TSQLSampleRecord; aParameters: PUTF8Char; const aSentData: RawUTF8; var aResp: RawUTF8; var aHead: RawUTF8):integer;
var aData: TSQLRawBlob;
    Values:Array of double;
begin
  result := 404; // invalid Request
  if (self=nil) or (aRecord=nil) or not aRecord.InheritsFrom(TSQLRecord) or
    (aRecord.ID<0) then
    exit; // we need a valid record and its ID
  if not RetrieveBlob(TSQLSampleRecord,aRecord.ID,'Wave',aData) then
    exit; // impossible to retrieve the Data BLOB field
    setLength(Values,Length(aData) div 4);
    Move(pointer(aData)^,Values[0],Length(aData));
  //aResp := JSONEncodeResult([SynCommons.BinToHex(aData)]);
    aResp:=JSONEncodeArray(Values,3);
  // idem: aResp := JSONEncode(['result',BinToHex(aRecord.fData)],TempMemoryStream);
  result := 200; // success
end;

supported the values is [116.40,112.54]
the right result JSONArray is [1.16E2,1.13E2] ,now the result is [2.18E14,0].why?

Offline

#12 2010-08-23 10:45:29

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,182
Website

Re: how to convert HeXstring to float Data

Perhaps you'll have to get the upcoming version 1.9, and the new JSONEncodeArray() methods.

Offline

#13 2010-08-23 12:11:50

longge007
Member
Registered: 2010-06-22
Posts: 107

Re: how to convert HeXstring to float Data

yeah, i have downloaded the New version 1.9 and now is using it (8.19 newest version).

Last edited by longge007 (2010-08-23 12:22:43)

Offline

#14 2011-01-18 16:39:25

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,182
Website

Re: how to convert HeXstring to float Data

There was a problem in ExtendedToString.
See "JSON floats decimal separator depends on language settings" ticket in http://synopse.info/fossil/tktview?name=6593f0fbd1

There is indeed a problem in the ExtendedToString() function. I used to override DecimalSeparator := '.' for the whole application, the use the SQLite3i18n unit to have all numerical conversions...

We have two possibilities:
- either use the already existing code for LVCL, which uses str and is quick enough IMHO;
- either override the global DecimalSeparator before using FloatToText.
Since the "str" resolution seems the easiest to implement (and is faster under Delphi 2009/2010/XE), I've used this.

Furthermore, the "str" solution is thread-safe, whereas the FloatToText is not - at least with Delphi 6.

Offline

Board footer

Powered by FluxBB