is there a support for 128 bit at 64 bit delphi?

Hi,
There is one bcd number has 20 digit. But it doesn't fit into 64 bit. 
It
needs 66 bit to store. Anyway I need to convert this 20 digit number
to hex format. I mean, input is 20 digit bcd number as string, output
should be hexadecimal number as string.
What is the pratical way to do this?
Thank you.
0
Mehmet
2/22/2012 8:32:08 PM
📁 embarcadero.delphi.win32
📃 2183 articles.
⭐ 0 followers.

💬 7 Replies
👁️‍🗨️ 1836 Views


> {quote:title=Mehmet Fide wrote:}{quote}
> Hi,
> 
> There is one bcd number has 20 digit. But it doesn't fit into 64 bit. 
> It
> needs 66 bit to store. Anyway I need to convert this 20 digit number
> to hex format. I mean, input is 20 digit bcd number as string, output
> should be hexadecimal number as string.
> 
> What is the pratical way to do this?
> 
> Thank you.
Google for BigInteger or BigDecimal Variant Delphi
Here is one - http://code.google.com/p/delphi-spring-framework/source/browse/trunk/Source/Core/Numerics/Spring.Numerics.BigDecimal.pas?r=258
0
An
2/22/2012 8:52:57 PM
> Google for BigInteger or BigDecimal Variant Delphi
> Here is one - 
> http://code.google.com/p/delphi-spring-framework/source/browse/trunk/Source/Core/Numerics/Spring.Numerics.BigDecimal.pas?r=258
Nice library. Thanks for it.
But still I wonder isn't there 128 bit native support in 64 bit mode?
0
Mehmet
2/22/2012 11:30:54 PM
"Mehmet Fide" wrote
> There is one bcd number has 20 digit. But it doesn't fit into 64 bit.
> It needs 66 bit to store. Anyway I need to convert this 20 digit number
> to hex format. I mean, input is 20 digit bcd number as string, output
> should be hexadecimal number as string.
> What is the practical way to do this?
Mehmet,
If it is just this one case, I would just make a string-in, string-out function
with my own big-integer accumulator from an array of three UInt32
variables and do a multiply x 10 and add for each new input decimal
digit. The second step, shifting the 4-bit nibbles into hexadecimal is
easy.
HTH, JohnH
0
John
2/23/2012 1:50:08 AM
Mehmet Fide wrote:
> Hi,
> 
> There is one bcd number has 20 digit. But it doesn't fit into 64 bit. 
> It
> needs 66 bit to store. Anyway I need to convert this 20 digit number
> to hex format. I mean, input is 20 digit bcd number as string, output
> should be hexadecimal number as string.
> 
> What is the pratical way to do this?
> 
> Thank you.
http://rvelthuis.de/programs/decimals.html
My Decimal type's mantissa can hold 96 bits. Convert the BCD to a
string (this is simple, as each nibble contains one digit), assign it
to a Decimal and get the bytes from the Decimal. These can then be
turned into a hex string again.
How is the BCD stored? Let's assume 10 bytes with the most significant
digit in the top 4 bits of the first byte:
  S := '';
  for I := 0 to 9 do
    S := S + Char(Ord('0') + Bytes[I] shr 4) + 
             Char(Ord('0') + Bytes[I| and $0F);
If the order is reverse (most significant digit in last byte), you can
do:
  S := '';
  for I := 0 to 9 do
    S := Char(Ord('0') + Bytes[I] shr 4) + 
         Char(Ord('0') + Bytes[I| and $0F) + S;
Now, if you have the number in a string (let's call it S) already, then
you don't need to do any of the above:
  var
    MyBytes: TBytes;
  MyDecimal := S; // converts string representation to Decimal with
                  // mantissa containing 96 bit number and scale of 0.
  MyBytes = MyDecimal.GetBytes; // lower 12 bytes (96 bits) are
mantissa
Now ignore the top Longword and use the remaining 96 bits to get your
hex:
  const 
    HexChars: array[0..15] of Char = '0123456789ABCDEF';
  var
    Hex: string;
  ...
  Hex := '';
  for J := 0 to 11 do
    Hex := HexChars[MyBytes[I] shr 4] + 
           HexChars[MyBytes[I] and $0F] + Hex; 
That will give you a 24 digit hex string. 
-- 
Rudy Velthuis
"He would make a lovely corpse."
 -- Charles Dickens (1812-1870)
0
Rudy
2/23/2012 8:00:10 PM
Rudy Velthuis (TeamB) has brought this to us :
>
> http://rvelthuis.de/programs/decimals.html
Hi,
Thanks a lot, this unit did the job directly :)
{Delphi}
function BytesToHex(aSource: TBytes): string;
begin
  SetLength(Result, Length(aSource) * 2);
  if Length(aSource) > 0 then
    BinToHex(aSource[0], PChar(Result), Length(aSource));
end;
procedure TForm1.Button1Click(Sender: TObject);
Var
  D: Decimal;
  B: TBytes;
begin
 D := '62636944367208999885';
 B := D.GetBytes;
 Memo1.Lines.Add(BytesToHex(B));
end;
{Delphi}
0
Mehmet
2/23/2012 10:39:26 PM
Mehmet Fide wrote:
> Rudy Velthuis (TeamB) has brought this to us :
> > 
> > http://rvelthuis.de/programs/decimals.html
> 
> Hi,
> 
> Thanks a lot, this unit did the job directly :)
> 
> {Delphi}
> function BytesToHex(aSource: TBytes): string;
> begin
>   SetLength(Result, Length(aSource) * 2);
>   if Length(aSource) > 0 then
>     BinToHex(aSource[0], PChar(Result), Length(aSource));
> end;
> 
> procedure TForm1.Button1Click(Sender: TObject);
> Var
>   D: Decimal;
>   B: TBytes;
> begin
>  D := '62636944367208999885';
>  B := D.GetBytes;
>  Memo1.Lines.Add(BytesToHex(B));
> end;
> {Delphi}
YAY!
-- 
Rudy Velthuis [TeamB]        http://rvelthuis.de
"I hear Glenn Hoddle has found God. That must have been one hell
 of a pass." -- Bob Davies.
0
Rudy
2/24/2012 10:44:35 AM
> What is the pratical way to do this?
20 digit binary requires 66 bits. bcd stores 2 digits in one byte. Delphi 
supports TBCD type (unit FMTBCD).
the program below runs fine in XE2
Ad Franse
program testfmtbcd;
{$APPTYPE CONSOLE}
{$R *.res}
uses
  System.SysUtils,
  fmtbcd,
  variants;
var length  : TBCD;
var width   : TBCD;
var height  : TBCD;
var content : TBCD;
var fs      : TFormatSettings;
var v       : variant;
begin
  fs                  := TFormatSettings.Create;
  fs.DecimalSeparator := '.';
  length  := strtoBCD('62636944367208999885' );
  width   := strtoBCD('1234567890.123456789', fs ) / 100.0;       // note the decimal point
  height  := 987654321098765.4 / 987654.3;
  content := length * width * height;
  writeln( 'l=' + formatbcd( '##############################.###################', length ));
  writeln( 'w=' + formatbcd( '##############################.###################', width  ));
  writeln( 'h=' + formatbcd( '##############################.###################', height ));
  writeln( 'c=' + formatbcd( '##############################.###################', content ));
  if content <> strtobcd( formatbcd( '##############################.###################', content + 1 )) then  // localized decimal point
    begin
      writeln( '*** The values of content and strtoBCD( formatBCD( ''' + formatbcd( '##############################.###################', content ) + ''')) are different' );
    end;
end.
0
Ad
2/27/2012 9:21:10 AM
Reply: