使用Ada2018(2012年增量),在循环结构中,我需要计算整数的第N根。
combinations.ads规范声明(使用GNAT )中,我有type Real is digits 6;combinations.adb中,我有一个过程构建,在开始之前,我实例化Ada的Generic_Elementary_Functions(Float),用package Fermat_math is new
Ada.Numerics.Generic_Elementary_Functions(Real) ;
use Fermat_math 稍后,在输出部分,我尝试:
-- -------------- 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…等等,但是我在不小心的版本控制中失去了它。
实际守则如下:
— 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;发布于 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
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;控制台:
√2: 1.41421E+00
√2: 1.41421E+00
√2: 1.41421E+00发布于 2022-07-13 04:34:19
Ada.Numerics.Generic_Elementary_Functions中的"**“运算符为您提供了查找浮点数的N根的能力。
下面的示例比较sqrt函数和"**“操作符的使用情况。
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;这个例子的结果是:
sqrt of 2.0 is: 1.41421E+00 and 1.41421E+00"**“算子的指数就是N的逆。
编辑:添加操作来计算一个数字的整数根。
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计算浮点根,然后将截断的结果转换为子类型自然。
此程序的示例执行如下:
Enter the base number: 10000
Enter the root: 20
The 20th root of 10000 is 1https://stackoverflow.com/questions/72960727
复制相似问题