• When using the Ada Big_Numbers.Big_Integers package, can the To_String

    From Kenneth Wolcott@21:1/5 to All on Wed Jul 26 22:26:24 2023
    Hi;

    When using the Ada Big_Numbers.Big_Integers package, can the To_String function output be sliced?

    I'd like to slice out the first two digits from the output of the To_String function of Ada.Big_Numbers.Big_Integers.

    When trying to do the usual string slicing on the output I get a silent failure, it is just as if I typed the null statement.

    Do I have to save the output to a variable via a declare block in order to get the slice to work?

    This question is prompted by my attempt to solve the Rosetta Code task:

    https://rosettacode.org/wiki/First_power_of_2_that_has_leading_decimal_digits_of_12

    Thanks,
    Ken Wolcott

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Jeffrey R.Carter@21:1/5 to Kenneth Wolcott on Thu Jul 27 10:53:35 2023
    On 2023-07-27 07:26, Kenneth Wolcott wrote:

    When using the Ada Big_Numbers.Big_Integers package, can the To_String function output be sliced?

    I'd like to slice out the first two digits from the output of the To_String function of Ada.Big_Numbers.Big_Integers.

    When trying to do the usual string slicing on the output I get a silent failure, it is just as if I typed the null statement.

    It would be helpful if you could show what you're doing and what results you get. This

    with Ada.Numerics.Discrete_Random;
    with Ada.Text_IO;

    procedure Func_Slice is
    subtype Digit is Character range '0' .. '9';

    package Random is new Ada.Numerics.Discrete_Random (Result_Subtype => Digit);

    Gen : Random.Generator;

    function Image (N : in Natural) return String is
    (if N = 0 then "" else Random.Random (Gen) & Image (N - 1) );
    -- Returns a string of N random Digits
    begin -- Func_Slice
    Random.Reset (Gen => Gen);
    Ada.Text_IO.Put_Line (Item => Image (10) (1 .. 2) );
    end Func_Slice;

    works as expected

    $ gnatmake -m -j0 -gnat12 -gnatan -gnato2 -O2 -fstack-check func_slice.adb x86_64-linux-gnu-gcc-12 -c -gnat12 -gnatan -gnato2 -O2 -fstack-check func_slice.adb
    x86_64-linux-gnu-gnatbind-12 -x func_slice.ali
    x86_64-linux-gnu-gnatlink-12 func_slice.ali -O2 -fstack-check
    $ ./func_slice
    10
    $ ./func_slice
    51

    --
    Jeff Carter
    "I would never want to belong to any club that
    would have someone like me for a member."
    Annie Hall
    41

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kenneth Wolcott@21:1/5 to Jeffrey R.Carter on Thu Jul 27 15:47:01 2023
    On Thursday, July 27, 2023 at 1:53:38 AM UTC-7, Jeffrey R.Carter wrote:
    On 2023-07-27 07:26, Kenneth Wolcott wrote:

    When using the Ada Big_Numbers.Big_Integers package, can the To_String function output be sliced?

    I'd like to slice out the first two digits from the output of the To_String function of Ada.Big_Numbers.Big_Integers.

    When trying to do the usual string slicing on the output I get a silent failure, it is just as if I typed the null statement.
    It would be helpful if you could show what you're doing and what results you get. This

    with Ada.Numerics.Discrete_Random;
    with Ada.Text_IO;

    procedure Func_Slice is
    subtype Digit is Character range '0' .. '9';

    package Random is new Ada.Numerics.Discrete_Random (Result_Subtype => Digit);

    Gen : Random.Generator;

    function Image (N : in Natural) return String is
    (if N = 0 then "" else Random.Random (Gen) & Image (N - 1) );
    -- Returns a string of N random Digits
    begin -- Func_Slice
    Random.Reset (Gen => Gen);
    Ada.Text_IO.Put_Line (Item => Image (10) (1 .. 2) );
    end Func_Slice;

    works as expected

    $ gnatmake -m -j0 -gnat12 -gnatan -gnato2 -O2 -fstack-check func_slice.adb x86_64-linux-gnu-gcc-12 -c -gnat12 -gnatan -gnato2 -O2 -fstack-check func_slice.adb
    x86_64-linux-gnu-gnatbind-12 -x func_slice.ali
    x86_64-linux-gnu-gnatlink-12 func_slice.ali -O2 -fstack-check
    $ ./func_slice
    10
    $ ./func_slice
    51

    Hi Jeff;

    After going back and exhaustively reviewing the AdaCore Learning Introduction sections on Strings and Arrays, I determined that I was not slicing with the correct syntax for what I wanted to obtain, it seems that I was slicing built-in whitespace, not
    the digits I was looking for. So I am now extracting the two-digit slice using (2 .. 3) rather than (1 .. 2) and I am now obtaining the desired output. What I was trying to do was to obtain the slice from the string on the fly, not first saving the
    string to a variable.

    This is what I have now (which works great): --------------------------------------------------------------------------- with Ada.Text_IO; use Ada.Text_IO;
    with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
    with Ada.Command_Line; use Ada.Command_Line;
    with Ada.Numerics.Big_Numbers.Big_Integers; use Ada.Numerics.Big_Numbers.Big_Integers;

    procedure Powers_Of_2_With_Leading_Digits_Of_12 is
    Max : Positive := Integer'Value (Argument (1));
    Powers_of_2 : Big_Positive := 1;
    begin
    for I in 1 .. Max loop
    Powers_of_2 := Powers_of_2 * To_Big_Integer (2);
    if I >= 4 then
    declare
    Powers_of_2_in_String_Format : String := To_String (Powers_of_2);
    First_Pair_of_String_Digits : String := Powers_of_2_in_String_Format (2 .. 3);
    begin
    if First_Pair_of_String_Digits = "12" then
    Put ("2^");
    Put (I, 0);
    Put_Line (To_String (Powers_of_2));
    end if;
    end; -- declare
    end if;
    end loop;
    end Powers_Of_2_With_Leading_Digits_Of_12; ---------------------------------------------------------------------------

    Now I can generalize this to more closely match the task requirements.

    I think I tried to incorrectly create the slice from the To_String output directly without creating the variable in which to store the slice, which then requires the declare block.

    Thanks,
    Ken

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From AdaMagica@21:1/5 to All on Fri Jul 28 10:19:03 2023
    To_String (Powers_of_2) (2 .. 3) should also work.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Simon Wright@21:1/5 to All on Fri Jul 28 19:21:08 2023
    This works for me:

    for I in 1 .. Max loop
    Powers_of_2 := Powers_of_2 * To_Big_Integer (2);
    if I >= 4 then
    if To_String (Powers_Of_2)(2 .. 3) = "12" then
    Put ("2^");
    Put (I, 0);
    Put_Line (To_String (Powers_of_2));
    end if;
    end if;
    end loop;

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kenneth Wolcott@21:1/5 to Simon Wright on Fri Jul 28 20:29:54 2023
    On Friday, July 28, 2023 at 11:21:13 AM UTC-7, Simon Wright wrote:
    This works for me:
    for I in 1 .. Max loop
    Powers_of_2 := Powers_of_2 * To_Big_Integer (2);
    if I >= 4 then
    if To_String (Powers_Of_2)(2 .. 3) = "12" then
    Put ("2^");
    Put (I, 0);
    Put_Line (To_String (Powers_of_2));
    end if;
    end if;
    end loop;


    Thanks to all for your responses...

    I don't know exactly what I had tried that had failed, but I have learned more now, especially to be more observant.

    I was able to simplify my code.

    Greatly appreciate your patience with me.

    Thanks,
    Ken

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From AdaMagica@21:1/5 to All on Sat Jul 29 04:07:15 2023
    Powers_of_2 := Powers_of_2 * To_Big_Integer (2);

    With the aspect Integer_Literal, also Powers_of_2 * 2 must work. The attributes Integer_Literal, Real_Literal, Put_Image make the new big numbers nearly work like numeric types (they are not). A difference: The range syntax for instance in loops A .. B
    is illegal.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kenneth Wolcott@21:1/5 to AdaMagica on Sat Jul 29 16:49:06 2023
    On Saturday, July 29, 2023 at 4:07:17 AM UTC-7, AdaMagica wrote:
    Powers_of_2 := Powers_of_2 * To_Big_Integer (2);
    With the aspect Integer_Literal, also Powers_of_2 * 2 must work. The attributes Integer_Literal, Real_Literal, Put_Image make the new big numbers nearly work like numeric types (they are not). A difference: The range syntax for instance in loops A .. B
    is illegal.

    I understand that the range syntax in loops implies that the loop variable is acting like an enumerated type which is not true for Big_Integers.

    What confused me is that I thought I had to convert the numeric literal (I'll have to go back and look at the package spec again to get this firmly understood.

    I have an another question about string slicing: I've tried (obviously incorrectly) to use a variable is one of the slice integers. Can this be done?

    Thanks,
    Ken

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kenneth Wolcott@21:1/5 to Kenneth Wolcott on Sat Jul 29 16:53:26 2023
    On Saturday, July 29, 2023 at 4:49:08 PM UTC-7, Kenneth Wolcott wrote:
    On Saturday, July 29, 2023 at 4:07:17 AM UTC-7, AdaMagica wrote:
    Powers_of_2 := Powers_of_2 * To_Big_Integer (2);
    With the aspect Integer_Literal, also Powers_of_2 * 2 must work. The attributes Integer_Literal, Real_Literal, Put_Image make the new big numbers nearly work like numeric types (they are not). A difference: The range syntax for instance in loops A ..
    B is illegal.
    I understand that the range syntax in loops implies that the loop variable is acting like an enumerated type which is not true for Big_Integers.

    What confused me is that I thought I had to convert the numeric literal (I'll have to go back and look at the package spec again to get this firmly understood.

    I have an another question about string slicing: I've tried (obviously incorrectly) to use a variable is one of the slice integers. Can this be done?

    Thanks,
    Ken

    Apparently not :-(

    gnatmake main.adb
    gcc -c main.adb
    main.adb:28:67: error: named parameters not permitted for attributes
    9 with Ada.Text_IO; use Ada.Text_IO;
    10 with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
    11 with Ada.Float_Text_IO; use Ada.Float_Text_IO;
    12 with Ada.Numerics.Elementary_Functions; use Ada.Numerics.Elementary_Functions;
    13 with Ada.Command_Line; use Ada.Command_Line;
    14
    15 procedure Main is
    16 Substr : String := Argument (1);
    17 Nth : Positive := Integer'Value (Argument (2));
    18 I, J : Natural;
    19 Temp : Float;
    20 begin
    21 I := 0;
    22 J := 0;
    23 loop
    24 I := I + 1;
    25 exit when I >= 10;
    26 Temp := 10.0 ** (log (2.0, 10.0) * Float (I));
    27 if I >= 4 then
    28 if (Float'Image (10.0 ** (log (2.0, 10.0) * Float (I)), Aft => 0, Exp => 0) (1 .. Substr'Length) = Substr then
    29 J := J + 1;
    30 if J = Nth then
    31 Put (I, 0);
    32 New_Line;
    33 exit;
    34 end if;
    35 end if;
    36 end if;
    37 end loop;
    38 end Main;

    Thanks,
    Ken

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Randy Brukardt@21:1/5 to Kenneth Wolcott on Sat Jul 29 23:43:53 2023
    'Image doesn't support any formatting, so no "Aft" or "Exp". The slicing
    isn't the problem. :-)

    You can use Text_IO to write to a string if you need formatting. 'Image is
    for quick & dirty debugging, not fancy output. (Of course, if you're lucky
    and it does what you need, then feel free to use it.)

    Randy.

    "Kenneth Wolcott" <kennethwolcott@gmail.com> wrote in message news:2a5702b3-dbbc-4255-a4d4-e801f227fed3n@googlegroups.com...
    On Saturday, July 29, 2023 at 4:49:08?PM UTC-7, Kenneth Wolcott wrote:
    On Saturday, July 29, 2023 at 4:07:17?AM UTC-7, AdaMagica wrote:
    Powers_of_2 := Powers_of_2 * To_Big_Integer (2);
    With the aspect Integer_Literal, also Powers_of_2 * 2 must work. The attributes Integer_Literal, Real_Literal, Put_Image make the new big numbers nearly work like numeric types (they are not). A difference: The range syntax for instance in loops A .. B is illegal.
    I understand that the range syntax in loops implies that the loop variable
    is acting like an enumerated type which is not true for Big_Integers.

    What confused me is that I thought I had to convert the numeric literal
    (I'll have to go back and look at the package spec again to get this
    firmly understood.

    I have an another question about string slicing: I've tried (obviously incorrectly) to use a variable is one of the slice integers. Can this be done?

    Thanks,
    Ken

    Apparently not :-(

    gnatmake main.adb
    gcc -c main.adb
    main.adb:28:67: error: named parameters not permitted for attributes
    9 with Ada.Text_IO; use Ada.Text_IO;
    10 with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
    11 with Ada.Float_Text_IO; use Ada.Float_Text_IO;
    12 with Ada.Numerics.Elementary_Functions; use Ada.Numerics.Elementary_Functions;
    13 with Ada.Command_Line; use Ada.Command_Line;
    14
    15 procedure Main is
    16 Substr : String := Argument (1);
    17 Nth : Positive := Integer'Value (Argument (2));
    18 I, J : Natural;
    19 Temp : Float;
    20 begin
    21 I := 0;
    22 J := 0;
    23 loop
    24 I := I + 1;
    25 exit when I >= 10;
    26 Temp := 10.0 ** (log (2.0, 10.0) * Float (I));
    27 if I >= 4 then
    28 if (Float'Image (10.0 ** (log (2.0, 10.0) * Float (I)), Aft =>
    0, Exp => 0) (1 .. Substr'Length) = Substr then
    29 J := J + 1;
    30 if J = Nth then
    31 Put (I, 0);
    32 New_Line;
    33 exit;
    34 end if;
    35 end if;
    36 end if;
    37 end loop;
    38 end Main;

    Thanks,
    Ken

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kenneth Wolcott@21:1/5 to Randy Brukardt on Mon Jul 31 12:36:31 2023
    On Saturday, July 29, 2023 at 9:43:42 PM UTC-7, Randy Brukardt wrote:
    'Image doesn't support any formatting, so no "Aft" or "Exp". The slicing isn't the problem. :-)

    You can use Text_IO to write to a string if you need formatting. 'Image is for quick & dirty debugging, not fancy output. (Of course, if you're lucky and it does what you need, then feel free to use it.)

    Hi Randy;

    Thank you for your input.

    I think I was (maybe I still am) suffering from the "sprintf" "disease" from Perl (and C).

    Thanks,
    Ken

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)