Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Float to String: Problem with string length

Tags:

ada

I would like to convert a float value to a String and created the following short example:

with Ada.Text_IO;

procedure Example is
   A : constant Float := -1.234;
   B : constant Float := 123_456.789;
   C : constant Float := 987.654_321;

   package Float_IO is new Ada.Text_IO.Float_IO (Num => Float);

   String_Float_A : String := "     ";
   String_Float_B : String := "          ";
   String_Float_C : String := "       ";
begin
   Ada.Text_IO.Put_Line (Float'Image (A));
   Ada.Text_IO.Put_Line (Float'Image (B));
   Ada.Text_IO.Put_Line (Float'Image (C));

   Float_IO.Put
     (To   => String_Float_A,
      Item => A,
      Aft  => 2,
      Exp  => 0);

   Float_IO.Put
     (To   => String_Float_B,
      Item => B,
      Aft  => 2,
      Exp  => 0);

   Float_IO.Put
     (To   => String_Float_C,
      Item => C,
      Aft  => 2,
      Exp  => 0);

   Ada.Text_IO.Put_Line (String_Float_A);
   Ada.Text_IO.Put_Line (String_Float_B);
   Ada.Text_IO.Put_Line (String_Float_C);
end Example;

My problem: I need to create the string variables before the call of the procedure Put with a sufficient length. How can this be done dynamically at runtime? Basically I need to figure out the number of digits before the dot. Then a sufficient string length would be: 1 (sign) + Number_Of_Dots + 1 (decimal separator) + Aft.

like image 297
Marcello90 Avatar asked May 12 '26 03:05

Marcello90


2 Answers

The number of digits before the dot of a decimal number can be computed calculating 1 plus the integer part of the common logarithm (base 10) of the integer part of the number.

In Ada:

    N := Integer (Float'Floor (Log (Float'Floor (abs X), 10.0))) + 1;

Your program must be with'ed with Ada.Numerics.Elementary_Functions. You must add a space for the minus sign if the number is negative.

This formula does not work if the integer part is 0, but then N is obviously 1.

like image 193
A.Cervetti Avatar answered May 16 '26 14:05

A.Cervetti


Your example uses Float, perhaps as a proxy for some more specific real type. If your actual data is better modeled as a decimal fixed point type, discussed here, don't overlook the convenience of Edited Output for Decimal Types, discussed here. The example below uses the string "+Z_ZZZ_ZZ9.99" to construct a picture of the desired output Image.

Console:

-        1.23
+  123,456.79
+      987.65
+1,000,000.00

Code:

with Ada.Text_IO;         use Ada.Text_IO;
with Ada.Text_IO.Editing; use Ada.Text_IO.Editing;

procedure Editing is

   type Number is delta 0.000_001 digits 12;
   type Numbers is array (Positive range <>) of Number;
   package Number_Output is new Decimal_Output (Number);
   Format_String : constant String  := "+Z_ZZZ_ZZ9.99";
   Format        : constant Picture := To_Picture (Format_String);
   Values        : constant Numbers :=
     (-1.234, 123_456.789, 987.654_321, Number'Last);

begin
   for Value of Values loop
      Put_Line (Number_Output.Image (Value, Format));
   end loop;

end Editing;

like image 43
trashgod Avatar answered May 16 '26 14:05

trashgod



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!