[Resolu  ]Stack over flow : calcul avec long_long_float

Stack over flow : calcul avec long_long_float [Resolu  ] - Ada - Programmation

Marsh Posté le 08-10-2015 à 20:12:59    

Je vous soumet un code qui génère chez moi stack ovver flow,
 
Je cherche comment faire tourner ce programmme.

Code :
  1. with Ada.Text_Io;
  2. use Ada;
  3. with Ada.Integer_Text_Io;
  4.  
  5. procedure Main is
  6.  
  7.  
  8.   type Sub_Sum_Type is new  Long_Long_Float Range Long_Long_Float'First..Long_Long_Float'Last;
  9.   package Sub_Sum_io is new Ada.Text_Io.Float_Io(Sub_Sum_Type);
  10.  
  11.  
  12.   Sub_Total_Max : Sub_Sum_Type := Sub_Sum_Type'Last/100_000_000_000.0;
  13.  
  14.   subtype Sub_Total_Type is Sub_Sum_Type range -(Sub_Total_Max)..Sub_Total_Max;
  15.  
  16.  
  17.   function Self (Operator : in String; Total : in Sub_Sum_Type; Sub_Total : in Sub_Total_Type) return Sub_Sum_Type is
  18.      
  19.      
  20.      Current_Char : Natural := 0;
  21.      
  22.      
  23.   begin
  24.      
  25.      if Operator ' Length > 0 then
  26.      Current_Char := Operator'First;
  27.      else
  28.      return Total + 0.0;
  29.      end if;
  30.      if Operator'Last > Operator'First then
  31.      for I in Operator'First+1..Operator'Last loop
  32.         case Operator(Current_Char) is
  33.            when '+' =>
  34.           if (((-(Total) - Sub_Total) + Sub_Sum_Type'Last) < 0.0) then
  35.              return Self (Operator(Operator'First..I), Total, Sub_Sum_Type'min(Sub_Sum_Type'Last, Sub_Total - 1.0));
  36.           else
  37.              return Total + Sub_Total;
  38.           end if;
  39.            when '=' =>
  40.           return TOtal + 0.0;
  41.         when others =>
  42.            null;
  43.         end case;
  44.      end loop;
  45.      else
  46.     
  47.      case Operator(Current_Char) is
  48.            when '+' =>
  49.           if (((-(Total) - Sub_Total) + Sub_Sum_Type'Last) < 0.0) then
  50.              return Self (Operator, Total, Sub_Sum_Type'min(Sub_Sum_Type'Last, Sub_Total - 1.0));
  51.           else
  52.              return Total + Sub_Total;
  53.           end if;
  54.            when '=' =>
  55.           return TOtal + 0.0;
  56.         when others =>
  57.            null;
  58.         end case;
  59.     
  60.      end if;
  61.      return 0.0;
  62.      end Self;
  63.  
  64.  
  65.      
  66.      
  67.      Sum : Sub_Sum_Type := Sub_Sum_Type'Last - Sub_Total_Type'last;
  68.      
  69.      Sub_Total : Sub_Total_Type := Sub_Total_Type'last;
  70.      
  71.      
  72. begin
  73.   Text_Io.Put("Initialization..." );
  74.   Text_Io.Put("Operator '=' :" );
  75.   sub_Sum_Io.Put(Self("=", Sum, Sub_Total));
  76.   Text_Io.Put("; Operator '+' :" );
  77.   sub_Sum_Io.Put(Self("+", Sum, Sub_Total));
  78.  
  79.   Sub_Total := Sub_Total + 0.01;
  80.  
  81.   for I in 1..Long_Long_Integer'Last loop
  82.      Text_Io.New_Line;
  83.      Text_Io.Put("Operator '=' :" );
  84.      Sum := Self("=", Sum, Sub_Total);
  85.      sub_Sum_Io.Put(Sum);
  86.      Text_Io.Put("; Operator '+' :" );
  87.      Sum := Self("+", Sum, Sub_Total);
  88.      sub_Sum_Io.Put(Sum);
  89.   end loop;
  90.  
  91.  
  92. end Main;


 
 
Ma commande :

$ ~/Self_Sum/main


 
 
She say :

Citation :


Initialization...Operator '=' : 1.18973149534533445E+4932; Operator '+' : 1.18973149535723177E+4932
Operator '=' : 1.18973149534533445E+4932; Operator '+' : 1.18973149535723177E+4932
Operator '=' : 1.18973149535723177E+4932; Operator '+' :
 

Spoiler :

raised STORAGE_ERROR : stack overflow or erroneous memory access



Message édité par Profil supprimé le 08-10-2015 à 22:08:28
Reply

Marsh Posté le 08-10-2015 à 20:12:59   

Reply

Marsh Posté le 08-10-2015 à 20:39:35    

Donc, j'a corrigé un peu mais ça passe toujours pas.
 
J'ai une fraction_first qui vaut beaucoup.
Ca représente le nombre potentielle de sommes effectuable par le programme.
 
maintenant ça plante à l'initialization du programme.

Initialization...Operator '=' : 3.40282E+38; Operator '+' :
 
raised STORAGE_ERROR : stack overflow or erroneous memory access


 

Code :
  1. with Ada.Text_Io;
  2. use Ada;
  3. with Ada.Integer_Text_Io;
  4.  
  5. procedure Main is
  6.  
  7.  
  8.   type Sub_Sum_Type is new  Float Range Float'First..Float'Last;
  9.   package Sub_Sum_io is new Ada.Text_Io.Float_Io(Sub_Sum_Type);
  10.  
  11.   Fraction_First : Sub_Sum_Type := 10_000_000_000_000_000.0;
  12.  
  13.   subtype Sub_Total_Type is Sub_Sum_Type range -(Sub_Sum_Type'last/Fraction_first)..Sub_Sum_Type'last/Fraction_First;
  14.  
  15.   Fraction_Total_Max : Sub_Sum_Type := Sub_Total_Type'Last/Fraction_First;
  16.  
  17.  
  18.  
  19.  
  20.  
  21.  
  22.  
  23.  
  24.  
  25.   function Self (Operator : in String; Total : in Sub_Sum_Type; Sub_Total : in Sub_Total_Type) return Sub_Sum_Type is
  26.      
  27.      
  28.      Current_Char : Natural := 0;
  29.      
  30.      
  31.   begin
  32.      
  33.      if Operator ' Length > 0 then
  34.      Current_Char := Operator'First;
  35.      else
  36.      return Total + 0.0;
  37.      end if;
  38.      if Operator'Last > Operator'First then
  39.      for I in Operator'First+1..Operator'Last loop
  40.         case Operator(Current_Char) is
  41.            when '+' =>
  42.           if (((-(Total) - Sub_Total) + Sub_Sum_Type'Last/Fraction_first) < 0.0) then
  43.              return Self (Operator(Operator'First..I), Total, Sub_Sum_Type'min(Sub_Total_Type'Last, Sub_Total - 1.0));
  44.           else
  45.              return Total + Sub_Total;
  46.           end if;
  47.            when '=' =>
  48.           return TOtal + 0.0;
  49.         when others =>
  50.            null;
  51.         end case;
  52.      end loop;
  53.      else
  54.     
  55.      case Operator(Current_Char) is
  56.            when '+' =>
  57.           if (((-(Total) - Sub_Total) + Sub_Sum_Type'Last/Fraction_first) < 0.0) then
  58.              return Self (Operator, Total, Sub_Sum_Type'min(Sub_Total_Type'Last, Sub_Total - 1.0));
  59.           else
  60.              return Total + Sub_Total;
  61.           end if;
  62.            when '=' =>
  63.           return TOtal + 0.0;
  64.         when others =>
  65.            null;
  66.         end case;
  67.     
  68.      end if;
  69.      return 0.0;
  70.      end Self;
  71.  
  72.  
  73.      
  74.      
  75.      Sum : Sub_Sum_Type := Sub_Sum_Type'Last - Sub_Total_Type'last;
  76.      
  77.      Sub_Total : Sub_Total_Type := Fraction_Total_Max;
  78.      
  79.      
  80. begin
  81.   Text_Io.Put("Initialization..." );
  82.   Text_Io.Put("Operator '=' :" );
  83.   sub_Sum_Io.Put(Self("=", Sum, Sub_Total));
  84.   Text_Io.Put("; Operator '+' :" );
  85.   sub_Sum_Io.Put(Self("+", Sum, Sub_Total));
  86.  
  87.  
  88.  
  89.   for I in 1..Long_Long_Integer'Last loop
  90.      Text_Io.New_Line;
  91.      Text_Io.Put("Operator '=' :" );
  92.      Sum := Self("=", Sum, Sub_Total);
  93.      sub_Sum_Io.Put(Sum);
  94.      Text_Io.Put("; Operator '+' :" );
  95.      Sum := Self("+", Sum, Sub_Total);
  96.      sub_Sum_Io.Put(Sum);
  97.      Text_Io.Put("; Sub Total : " );
  98.      sub_Sum_Io.Put(Sub_Total);
  99.   end loop;
  100.  
  101.  
  102. end Main;

Reply

Marsh Posté le 08-10-2015 à 21:06:39    

Waouh !
 
Ca tourne.
 
 
Maj du code. pour ceux et celles que ça amuse :
 
 
 
 
 

Code :
  1. -- Programme qui cherche la somme maximum additionnable à une somme.plus grande.
  2.  
  3. with Ada.Text_Io;
  4. use Ada;
  5. with Ada.Integer_Text_Io;
  6.  
  7. procedure Main is
  8.  
  9.  
  10.   type Sub_Sum_Type is new  Float Range Float'First..Float'Last;
  11.   package Sub_Sum_io is new Ada.Text_Io.Float_Io(Sub_Sum_Type);
  12.  
  13.   Fraction_First : Sub_Sum_Type := 10_000_000_000_000_000.0;
  14.  
  15.   subtype Sub_Total_Type is Sub_Sum_Type range -(Sub_Sum_Type'last/Fraction_first)..Sub_Sum_Type'last/Fraction_First;
  16.  
  17.   Fraction_Total_Max : Sub_Sum_Type := Sub_Total_Type'Last;
  18.  
  19.  
  20.  
  21.  
  22.  
  23.  
  24.  
  25.  
  26.  
  27.   function Self (Operator : in String; Total : in Sub_Sum_Type; Sub_Total : in Sub_Total_Type) return Sub_Sum_Type is
  28.      
  29.      
  30.      Current_Char : Natural := 0;
  31.      
  32.      
  33.   begin
  34.      
  35.      if Operator ' Length > 0 then
  36.      Current_Char := Operator'First;
  37.      else
  38.      return Total + 0.0;
  39.      end if;
  40.      if Operator'Last > Operator'First then
  41.      for I in Operator'First+1..Operator'Last loop
  42.         case Operator(Current_Char) is
  43.            when '+' =>
  44.           if (((-(Total) - Sub_Total) + Sub_Sum_Type'Last/Fraction_first) < 0.0) then
  45.              return Self (Operator(Operator'First..I), Total, Sub_Sum_Type'min(Sub_Total_Type'Last, Sub_Total / Fraction_first));
  46.           else
  47.              return Total + Sub_Total;
  48.           end if;
  49.            when '=' =>
  50.           return TOtal + 0.0;
  51.            when others =>
  52.           null;
  53.         end case;
  54.      end loop;
  55.      else
  56.     
  57.      case Operator(Current_Char) is
  58.         when '+' =>
  59.            if (((-(Total) - Sub_Total) + Sub_Sum_Type'Last) < 0.0) then
  60.           return Self (Operator, Total, Sub_Sum_Type'min(Sub_Total_Type'Last, Sub_Total / Fraction_first));
  61.            else
  62.           return Total + Sub_Total;
  63.            end if;
  64.         when '=' =>
  65.            return TOtal + 0.0;
  66.         when others =>
  67.            null;
  68.      end case;
  69.     
  70.      end if;
  71.      return 0.0;
  72.   end Self;
  73.  
  74.  
  75.      
  76.      
  77.      Sum : Sub_Sum_Type := Sub_Sum_Type'Last - Sub_Total_Type'Last*Fraction_first;
  78.      
  79.      Sub_Total : Sub_Total_Type := Sum - (Sum - Fraction_Total_Max);
  80.      
  81.      
  82. begin
  83.   Text_Io.Put("Initialization..." );
  84.   Text_Io.Put("Operator '=' :" );
  85.   sub_Sum_Io.Put(Self("=", Sum, Sub_Total));
  86.   Text_Io.Put("; Operator '+' :" );
  87.   sub_Sum_Io.Put(Self("+", Sum, Sub_Total));
  88.  
  89.  
  90.  
  91.   for I in 1..5 loop  
  92.   Text_Io.New_Line;
  93.   Text_Io.Put("Operator '=' :" );
  94.   Sum := Self("=", Sum, Sub_Total);
  95.   sub_Sum_Io.Put(Sum);
  96.   Text_Io.Put("; Operator '+' :" );
  97.   Sum := Self("+", Sum, Sub_Total);
  98.   sub_Sum_Io.Put(Sum);
  99.   Text_Io.Put("; Sub Total : " );
  100.   sub_Sum_Io.Put(Sub_Total);
  101.   end loop;
  102.  
  103.  
  104. end Main;


Message édité par Profil supprimé le 08-10-2015 à 21:07:43
Reply

Marsh Posté le 08-10-2015 à 22:07:59    

Celui- ci est plus aboutit.
 

Code :
  1. with Ada.Text_Io;
  2. use Ada;
  3. with Ada.Integer_Text_Io;
  4.  
  5. procedure Main is
  6.  
  7.   -- Ici on définit l'intervale dans lequel on accepte la somme maximale.
  8.   type This_Float_Type is new Float range -1_000_000.0..1_000_000.0;
  9.  
  10.   -- on defini un sous type local.
  11.   type Sub_Sum_Type is new  This_Float_Type Range This_Float_type'First..This_Float_type'Last;
  12.  
  13.   --Pour les entrée sorties textuelle de valeurs du type local.
  14.   package Sub_Sum_io is new Ada.Text_Io.Float_Io(Sub_Sum_Type);
  15.  
  16.   -- le minimum d'addition possible.
  17.   Fraction_First : Sub_Sum_Type := 10.0;
  18.  
  19.   -- un sous-type représentant l'intervale de la fraction maximale sommable.
  20.   subtype Sub_Total_Type is Sub_Sum_Type range -(Sub_Sum_Type'last/Fraction_first)..Sub_Sum_Type'last/Fraction_First;
  21.  
  22.   -- la fraction maximale sommable.
  23.   Fraction_Total_Max : Sub_Sum_Type := Sub_Total_Type'Last;
  24.  
  25.  
  26.  
  27.   function Self (Operator : in String; Total : in Sub_Sum_Type; Sub_Total : in Sub_Total_Type) return Sub_Sum_Type is
  28.      
  29.      
  30.      Current_Char : Natural := 0;
  31.      
  32.      
  33.   begin
  34.      
  35.      if Operator ' Length > 0 then
  36.      Current_Char := Operator'First;
  37.      else
  38.      return Total + 0.0;
  39.      end if;
  40.  
  41.      -- la c'est en prevision de la suite du code.
  42.      if Operator'Last > Operator'First then
  43.      for I in Operator'First+1..Operator'Last loop
  44.         case Operator(Current_Char) is
  45.            when '+' =>
  46.           if (((-(Total) - Sub_Total) + Sub_Sum_Type'Last/Fraction_first) < 0.0) then
  47.             
  48.              return Self (Operator(Operator'First..I), Total, Sub_Sum_Type'min(Sub_Total_Type'Last, Sub_Total - Sub_Total / Fraction_first));
  49.           else
  50.              return Sub_Total;
  51.           end if;
  52.            when '=' =>
  53.           return TOtal + 0.0;
  54.            when others =>
  55.           null;
  56.         end case;
  57.      end loop;
  58.      else
  59.      -- ici on traite notre cas à un caractère dans l'opérateur attendu.
  60.      case Operator(Current_Char) is
  61.         when '+' =>
  62.  
  63.               -- Si l'addition dépasse on r'appelle la fonction avec une sous-fraction de fraction.
  64.  
  65.            if (((-(Total) - Sub_Total) + Sub_Sum_Type'Last) < 0.0) then
  66.           return Self (Operator, Total, Sub_Sum_Type'min(Sub_Total_Type'Last, Sub_Total - Sub_Total / Fraction_first));
  67.            else
  68.  
  69.                  -- Si non.. Si ça passe on retounre le sous-total sommable.
  70.           return Sub_Total;
  71.            end if;
  72.         when '=' =>
  73.            return Total + 0.0;
  74.         when others =>
  75.            null;
  76.      end case;
  77.     
  78.      end if;
  79.      return 0.0;
  80.   end Self;
  81.  
  82.  
  83.      
  84.      
  85.   Sum : Sub_Sum_Type := 0.0;
  86.  
  87.   Sub_Total : Sub_Total_Type := 501.0;
  88.      
  89.      -- Test.
  90. begin
  91.   Text_Io.Put_line("Initialization..." );
  92.   Text_Io.Put("Operator '=' :" );
  93.   sub_Sum_Io.Put(Self("=", Sum, Sub_Total));
  94.   Text_Io.Put("; Operator '+' :" );
  95.   sub_Sum_Io.Put(Self("+", Sum, Sub_Total));
  96.  
  97.  
  98.  
  99.   while not (Sum >= 1000_000.0) loop  
  100.      Text_Io.New_Line;
  101.      Text_Io.Put("Operator '=' :" );
  102.      Sum := Self("=", Sum, Sub_Total);
  103.      sub_Sum_Io.Put(Sum);
  104.      Text_Io.Put("; Operator '+' :" );
  105.      Sub_Total := Self("+", Sum, Sub_Total);
  106.      sub_Sum_Io.Put(Sub_Total);
  107.      Text_Io.Put("; Total : " );
  108.      Sum := Sum + (Sub_Total);
  109.      sub_Sum_Io.Put(sum);
  110.  
  111.   end loop;
  112.  
  113.  
  114. end Main;


 
Merci.

Reply

Marsh Posté le 09-10-2015 à 01:00:52    

Code finalisé :
 

Code :
  1. with Ada.Text_Io;
  2. use Ada;
  3. with Ada.Integer_Text_Io;
  4.  
  5. procedure Main is
  6.  
  7.   package Sub_Sum_io is new Ada.Text_Io.Float_Io(Float);
  8.   generic
  9.      B_Inf : Float;
  10.      B_Sup : Float := Float'Last;
  11.   package Echeancier is
  12.      
  13.      
  14.      subtype This_Float_Type is Float range 0.0..B_inf;
  15.      
  16.      subtype Sub_Sum_Type is This_Float_Type Range This_Float_type'First..This_Float_type'Last;
  17.      
  18.      
  19.      
  20.      
  21.      subtype Sub_Total_Type is Sub_Sum_Type range 0.0..Sub_Sum_Type(B_Sup);  
  22.  
  23.      
  24.  
  25.  
  26.  
  27.  
  28.      function Self (Operator : in String; Total : in float; Sub_Total : in Sub_Total_Type; Sum : in Sub_Sum_type) return Sub_Total_Type;
  29.  
  30.   end Echeancier;
  31.  
  32.   package body Echeancier is
  33.  
  34.  
  35.      function Self (Operator : in String; Total : in float; Sub_Total : in Sub_Total_Type; Sum : in Sub_Sum_type) return Sub_Total_Type is
  36.     
  37.     
  38.      Current_Char : Natural := 0;
  39.      
  40.      Fraction : Float := Float(Sub_total/(Sum/Sub_Total));
  41.      
  42.      begin
  43.      
  44.      if Operator ' Length > 0 then
  45.         Current_Char := Operator'First;
  46.      else
  47.         return Total + 0.0;
  48.      end if;
  49.     
  50.     
  51.      case Operator(Current_Char) is
  52.         when '+' =>
  53.            if Total < sum and Float(Total + Sub_Total) > Float(Sum) Then
  54.           return Self (Operator, Total, Sub_Total_Type'max(0.01, Sub_Total - Fraction), sum);
  55.            else
  56.           return Sub_Total;
  57.            end if;
  58.         when '=' =>
  59.            return Sub_Total + 0.0;
  60.         when others =>
  61.            null;
  62.      end case;
  63.     
  64.  
  65.      return 0.0;
  66.      end Self;
  67.      
  68.      
  69.      
  70.      
  71.      
  72.      
  73.      
  74.   end Echeancier;
  75.      
  76.  
  77.  
  78.   Sum : float := 0.0;
  79.  
  80.   Sub_Total : Float := 0.0;
  81.  
  82. begin
  83.      
  84.  
  85.   Text_Io.Put("Entrez un la valeur Cible > 0.0 et validez par la touche ""Entrée"": " );
  86.   Sub_Sum_Io.Get(Sum);
  87.   Text_Io.Put("Entrez un la raison maximale > 0.0 et validez par la touche ""Entrée"": " );
  88.   Sub_Sum_Io.Get(Sub_total);
  89.  
  90.   declare
  91.      package Mon_Echeancier is new Echeancier(Sum, Sub_Total);
  92.      
  93.      use Mon_Echeancier;
  94.            
  95.      Cible : constant Sub_Sum_Type := Sub_Sum_Type(Sum);
  96.      
  97.   begin
  98.      Sum := 0.0;
  99.      Text_Io.Put_line("Initialization..." );
  100.      Text_Io.Put("Operator '=' :" );
  101.      sub_Sum_Io.Put(Float(Self("=", Sub_Sum_Type(Sum), Sub_Total_Type(Sub_Total), cible)));
  102.      Text_Io.Put("; Operator '+' :" );
  103.      sub_Sum_Io.Put(Float(Self("+", Sub_Sum_Type(Sum), Sub_Total_Type(Sub_Total), cible)));
  104.      
  105.      loop
  106.      exit when (Sum + Sub_total > Float(Cible));
  107.      Text_Io.New_Line;
  108.      Text_Io.Put("Operator '=' :" );
  109.      Sum := Sum + Float(Self("=", Sub_Sum_Type(Sum), Sub_total_Type(Sub_total), cible));
  110.     
  111.      sub_Sum_Io.Put(Sum);
  112.      Text_Io.Put("; Operator '+' :" );
  113.      Sub_Total := Float(Self("+", Sub_Sum_Type(Sum), Sub_Total_type(Sub_Total), cible));
  114.      sub_Sum_Io.Put(Sub_Total);
  115.     
  116.     
  117.     
  118.     
  119.     
  120.      end loop;
  121.   end;
  122.      
  123. end Main;


 
Exemple :
 

Entrez un la valeur Cible > 0.0 et validez par la touche "Entrée": 1_010.1
Entrez un la raison maximale > 0.0 et validez par la touche "Entrée": 1_001.01
Initialization...
Operator '=' : 1.00101E+03; Operator '+' : 1.00101E+03
Operator '=' : 1.00101E+03; Operator '+' : 9.00818E+00
Operator '=' : 1.01002E+03; Operator '+' : 8.17839E-02
Operator '=' : 1.01010E+03; Operator '+' : 8.17839E-02

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed