首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Ada,使用Ada.Numerics.Generic_Elementary_Functions(Real),实例计算N个根并输出

使用Ada,使用Ada.Numerics.Generic_Elementary_Functions(Real),实例计算N个根并输出
EN

Stack Overflow用户
提问于 2022-07-13 03:51:29
回答 2查看 131关注 0票数 0

使用Ada2018(2012年增量),在循环结构中,我需要计算整数的第N根。

  1. 在我的包combinations.ads规范声明(使用GNAT )中,我有
代码语言:javascript
复制
type Real           is digits 6;
  1. 在package combinations.adb中,我有一个过程构建,在开始之前,我实例化Ada的Generic_Elementary_Functions(Float),用
代码语言:javascript
复制
package Fermat_math is new
   Ada.Numerics.Generic_Elementary_Functions(Real)  ;
   use Fermat_math 

稍后,在输出部分,我尝试:

代码语言:javascript
复制
-- -------------- buggy, fix
--   combo_sum_root := Fermat_math.Exp (Log (Integer(combo_sum_root) / n);  — n is integer type
     combo_sum_root := Real(combo_sum) ** (1/n) ; 
-- -------------

   put(" and sum's root is ");
   put(combo_sum_root'image );  —  -- gives all roots as 1.00000E+00

几周前我就让它工作了,根= 3.878…等等,但是我在不小心的版本控制中失去了它。

实际守则如下:

代码语言:javascript
复制
— combinations.ads specification ------------------------------------------
with gearbox;
use  gearbox;
with Ada.Float_Text_IO  ; use Ada.Float_Text_IO;

with Ada.Text_IO;  use Ada.Text_IO;
with Ada.Numerics; use Ada.Numerics;

with Ada.Numerics.Elementary_Functions;
use  Ada.Numerics.Elementary_Functions;

package combinations is

type combo_action   is (add_element,clear, show, show_sum, Build);
type Real           is digits 6    ;

combo_sum_root      : Real         ;
i,n,b, combos_cnt
,combo_sum          : integer      ;

procedure get_parms                ;
Procedure build  (b,n,r:integer)   ;

end combinations;

-- combinations.adb BODY ---------------------------------------
with Text_IO              ;  use Text_IO;
with Ada.Text_IO          ;  use Ada.Text_IO;
with Ada.INteger_Text_IO  ;  use Ada.Integer_Text_IO;
with Ada.Strings.Unbounded;  use Ada.Strings.UNbounded;
with gearbox              ;  use gearbox;
with Ada.Numerics.Generic_Elementary_Functions ;

package body combinations is

group, Intersection_count,r     : Integer              ;
done, get_value                 : boolean := false     ;
CR: constant Character := Character'Val (13)           ;
type gear_arrays is array(positive range <>) of integer;

-- ------------------------------------------------------------


procedure get_parms is
begin
...

 end get_parms ;

-- --------------------------------------------------
 procedure build  (b,n,r: Integer) is
-- --------------------------------------------------
cnt, e_cnt, value                : integer :=0      ;
launch, pause                    : character        ;
run_again                        : String := " "    ;
show_group                       : Unbounded_string ;
all_done, combo_done             : boolean := false ;
combo_sum_root                   : Real             ;
progress_string : Unbounded_String                  ;
gears:gear_array     (1..r)                         ;

-- with Ada.Numerics.Generic_Elementary_Functions   ;  — in specification .ads file
 package Fermat_math is new
  Ada.Numerics.Generic_Elementary_Functions(Real)  ;
 use Fermat_math                                   ;

begin
...
...

put("Selecting "); -- put(tot_combos, width=>1);
put(" Possible Combinations,"); New_line;
While Not all_done loop  -- for all/x combiNatioNs
 ...  
end loop;
   -- ------------------------
   combo_sum := 0;
   for e in  1..r loop  -- select r value, element of grou & size of combiatios
     value := fermats(gears(e).position,1);
     ...
   put ("Combination sum is "); put (combo_sum, width => 1);
  …..
  -- -------------- buggy, fix
--   combo_sum_root := Fermat_math.Exp (Log (Integer(combo_sum_root) / n);
 combo_sum_root := Real(combo_sum) ** (1/n) ; 
  -- -------------

   put(" and sum's root is ");
   put(combo_sum_root'image );  -- gives all roots as 1.00000E+00

   end loop;

     group := group + 1;  --
   end if;  -- is New group and shift
  end loop;  -- Not all doNe

 eNd build;
begin   -- package
 Null;
end combinations;
EN

回答 2

Stack Overflow用户

发布于 2022-07-13 22:16:42

您的示例中的关键问题是"n是整数类型“。尝试创建有理指数时,表达式1/n的计算结果为值为零的Integer。包Generic_Elementary_Functions要求“由零指数进行幂运算产生值1”。

解决方案是在创建指数时使用Real类型:1.0 / Real(N)。在@Jim的示例上展开,下面的代码还说明了计算https://en.wikipedia.org/wiki/Exponentiation#Powers_via_logarithms

代码语言:javascript
复制
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Numerics.Generic_Elementary_Functions;

procedure Nth_Root is

   type Real is digits 6;
   package Real_Functions is new Ada.Numerics.Generic_Elementary_Functions
     (Real);
   use Real_Functions;

   N     : constant Natural := 2;
   Power : constant Real    := 1.0 / Real(N);
   Base  : constant Real    := 2.0;

begin
   Put_Line ("√2:" & Real'Image (Sqrt (Base)));
   Put_Line ("√2:" & Real'Image (Base**Power));
   Put_Line ("√2:" & Real'Image (Exp (Power * Log (Base))));
end Nth_Root;

控制台:

代码语言:javascript
复制
√2: 1.41421E+00
√2: 1.41421E+00
√2: 1.41421E+00
票数 3
EN

Stack Overflow用户

发布于 2022-07-13 04:34:19

Ada.Numerics.Generic_Elementary_Functions中的"**“运算符为您提供了查找浮点数的N根的能力。

下面的示例比较sqrt函数和"**“操作符的使用情况。

代码语言:javascript
复制
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Numerics.Generic_Elementary_Functions;

procedure Main is
   type Real is digits 6;
   package Real_Functions is new Ada.Numerics.Generic_Elementary_Functions(Real);
   use Real_Functions;
   
   base  : Real := 2.0;
   Power : Real := 1.0 / 2.0;
begin
   Put_Line("sqrt of 2.0 is: " & Real'Image(sqrt(base)) & " and " &
              Real'Image(base**Power));
end Main;

这个例子的结果是:

代码语言:javascript
复制
sqrt of 2.0 is:  1.41421E+00 and  1.41421E+00

"**“算子的指数就是N的逆。

编辑:添加操作来计算一个数字的整数根。

代码语言:javascript
复制
with Ada.Text_IO;         use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Numerics.Generic_Elementary_Functions;

procedure integer_roots is
   function int_root (Num : Positive; Exponent : Positive) return Natural is
      type Real is digits 6;
      package real_functions is new Ada.Numerics.Generic_Elementary_Functions
        (Real);
      use real_functions;
      Real_Num      : Real := Real (Num);
      Real_Exponent : Real := 1.0 / Real (Exponent);
      Real_Result   : Real := Real_Num**Real_Exponent;
   begin
      return Natural (Real'Truncation (Real_Result));
   end int_root;

   Num      : Positive;
   Exponent : Positive;
begin
   Put ("Enter the base number: ");
   Get (Num);
   Skip_Line;
   Put ("Enter the root: ");
   Get (Exponent);

   Put_Line
     ("The" & Exponent'Image & "th root of" & Num'Image & " is" &
      Natural'Image (int_root (Num, Exponent)));
end integer_roots;

上面显示的函数int_root计算浮点根,然后将截断的结果转换为子类型自然。

此程序的示例执行如下:

代码语言:javascript
复制
Enter the base number: 10000
Enter the root: 20
The 20th root of 10000 is 1
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72960727

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档