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

```
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
```

```
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
```

To_String (Powers_of_2) (2 .. 3) should also work.

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;

```
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
```

```
> 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.
```

```
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
```

```
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
```

```
'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
```

```
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
```