• Jon © (18.01.08 04:46) [0]
    I notice that there are several conversions missing in KOL.
    Can I request that they are added to make the library more complete.

    Some that I can think of are:

    Hex2Int64,
    Rome2Int,
    Int64_2Rome,
    Rome2Int64,
    Int2Octal,
    Octal2Int64
    Int64_2Octal,
    Int2Binary,
    Binary2Int64
    Int64_2Binary

    There are probably more...

    The above have at least one direction of conversion currently implemented in KOL.PAS
  • =BuckLr= © (18.01.08 14:04) [1]
    I quite agree with you...
    Поддерживаю Jon'а!
  • Vladimir Kladov © (19.01.08 10:50) [2]
    Rome2Int64 not necessary still T=10000 and it is very hard to take a big enough number in Rome numbers.
  • D[u]fa (19.01.08 13:36) [3]
    раз поддерживаете, то напишите, а их добавят
  • =BuckLr= © (20.01.08 11:02) [4]

    > напишите, а их добавят

    Не вопрос, но точно ли добавят? Может, аффтар против... Вот и спрашиваем сначала
  • Vladimir Kladov © (20.01.08 11:36) [5]
    добавлю. Просто я обычно сам делаю то, что мне самому понадобилось. Можно было бы оставлять в отдельном модуле, но это неразумно: Delphi для каждого модуля добавляет 56 байт кода, если модулей много, это выливается. Оставлять опять же только для себя неразумно: чем больше народу протетирует, тем больше ошибок выловится. А добавлять просто для полноты коллекции, пока оно не понадобилось - тоже не очень разумно: протестировать будет некому, и годами в модуле будет лежать непроверенный и наверняка ошибочный кусок кода. Так что пишите, тестируйте - добавим.
  • engine © (20.01.08 18:05) [6]
    Вот написал, если кому потребуется сиё творение.
    Работает правда только с положительными числами

    unit Conversions;

    interface

    function IntToHex(Src: LongWord): String;
    function IntToOct(Src: LongWord): String;
    function IntToBinary(Src: LongWord): String;
    function HexToInt(Src : String) : LongWord;
    function OctToInt(Src : String) : LongWord;
    function BinToInt(Src : String) : LongWord;

    implementation

    function IntToHex(Src: LongWord): String;
    const DICT = '0123456789ABCDEF';
    begin
     Result := '';
     repeat
       Result := DICT[(Src mod 16) + 1] + Result;
       Src := Src div 16;
     until (Src div 16) = 0;
     Result := DICT[(Src mod 16) + 1] + Result;
    end;

    function IntToOct(Src: LongWord): String;
    const DICT = '01234567';
    begin
     Result := '';
     repeat
       Result := DICT[(Src mod 8) + 1] + Result;
       Src := Src div 8;
     until (Src div 8) = 0;
     Result := DICT[(Src mod 8) + 1] + Result;
    end;

    function IntToBinary(Src: LongWord): String;
    const DICT = '01';
    begin
     Result := '';
     repeat
       Result := DICT[(Src mod 2) + 1] + Result;
       Src := Src div 2;
     until (Src div 2) = 0;
     Result := DICT[(Src mod 2) + 1] + Result;
    end;

    function HexToInt(Src : String) : LongWord;
    const DICT = '0123456789ABCDEF';
    var i : Integer;
    begin
     Result := 0;
     for i := 1 to Length(Src)-1 do
     begin
       Result := (Result + (pos(Src[i],DICT) — 1)) * 16;
     end;
     Result := Result + pos(Src[Length(Src)],DICT) —1;
    end;

    function OctToInt(Src : String) : LongWord;
    const DICT = '01234567';
    var i : Integer;
    begin
     Result := 0;
     for i := 1 to Length(Src)-1 do
     begin
       Result := (Result + (pos(Src[i],DICT) — 1)) * 8;
     end;
     Result := Result + pos(Src[Length(Src)],DICT) —1;
    end;

    function BinToInt(Src : String) : LongWord;
    const DICT = '01';
    var i : Integer;
    begin
     Result := 0;
     for i := 1 to Length(Src)-1 do
     begin
       Result := (Result + (pos(Src[i],DICT) — 1)) * 2;
     end;
     Result := Result + pos(Src[Length(Src)],DICT) —1;
    end;

    end.

  • engine © (20.01.08 21:41) [7]
    > [6] engine ©   (20.01.08 18:05)

    Чтобы переводила отрицательные числа, добавляем такую строчку в начало функций IntToXXX:

    if Src < 0 then Src := high(Src) &#151; Src;

  • =BuckLr= © (20.01.08 22:03) [8]
    IntToHex=Int2Hex
  • engine © (21.01.08 00:42) [9]
    > [8] =BuckLr= ©   (20.01.08 22:03)

    Это единственное замечание к моим функциям?
  • Elec3C © (21.01.08 14:14) [10]
    Может деление лучше заменить на сдвиг вправо? Или нет?
  • Vladimir Kladov © (21.01.08 16:09) [11]
    Насколько я понял Jon'а его интересует int64. У нас уже есть Int2Hex (кстати, в нем есть полезная возможность сразу указать минимальное число цифр) и Hex2Int. Мой вариант будет такой:

    function ToRadix( number: Radix_Int; radix: Integer; min_digits: Integer ): KOLString;
    var Buf: array[ 0..64 ] of KOLChar;
       p: PKOLChar;
       n: Integer;
       numd: Extended;
    begin
     Assert( (radix >= 2) and (radix <= 36), 'Radix base must be between 2 and 36' );
     Assert( min_digits <= 64, 'Maximum possible digits number is 64' );
       p := @ Buf[ 64 ];
       p^ := #0;
       while (number <> 0) do
       begin
           dec( p );
           {$IFDEF _D5orHigher}
           if number < 0 then
           begin
               numd := 1.0 * I64( number ).Hi * $100000000 + I64( number ).Lo;
               number := Round( numd / radix );
               n := Round( numd - 1.0 * number * radix );
               if n < 0 then
               begin
                 n := radix + n;
                 dec( number );
               end;
           end
             else
           {$ENDIF}
           begin
               n := number mod radix;
               number := number div radix;
           end;
           if n <= 9 then p^ := KOLChar( n + Ord( '0' ) )
           else p^ := KOLChar( n - 10 + Ord( 'A' ) );
           dec( min_digits );
       end;
       while (min_digits > 0) do
       begin
           dec( p );
           p^ := '0';
           dec( min_digits );
       end;
       Result := p;
    end;

    function FromRadixStr( var Rslt: Radix_int; s: PKOLChar; radix: Integer ): PKOLChar;
    var n: Integer;
    begin
     Assert( (radix >= 2) and (radix <= 36), 'Radix base must be between 2 and 36' );
       Rslt := 0;
       while s^ <> #0 do
       begin
           CASE s^ OF
           '0'..'9': n := Ord( s^ ) - Ord( '0' );
           'a'..'z': n := Ord( s^ ) - Ord( 'a' ) + 10;
           'A'..'Z': n := Ord( s^ ) - Ord( 'A' ) + 10;
           else n := 100;
           END;
           if n >= radix then break;
           Rslt := Rslt * radix + n;
           inc( s );
       end;
       Result := s;
    end;

    function FromRadix( const s: String; radix: Integer ): Radix_int;
    begin
       Result := 0;
       if s = '' then Exit;
       FromRadixStr( Result, @ s[ 1 ], radix );
    end;


  • Vladimir Kladov © (21.01.08 16:21) [12]
    Да забыл при интерфейсные декларации

    type Radix_int = {$IFDEF _D5orHigher} Int64 {$ELSE} Integer {$ENDIF};
    function ToRadix( number: Radix_int; radix, min_digits: Integer ): String;
    {* Converts unsigned number to string representing it literally in a numeric
      base given by radix parameter. }

    function FromRadixStr( var Rslt: Radix_int; s: PKOLChar; radix: Integer ): PKOLChar;
    {* Converts unsigned number from string representation in a numeric base given by
      a radix parameter. Returns a pointer to a character next to the last digit of
      the number. }

    function FromRadix( const s: String; radix: Integer ): Radix_int;
    {* Converts unsigned number from string representation in a numeric base given by
      a radix parameter. See also: FromRadixStr function. }


  • Jon © (22.01.08 02:06) [13]

    > engine

    Good code - thanks.

    > Vladimir Kladov

    I respect the master! :-)
Есть новые Нет новых   [134431   +11][b:0][p:0.004]