【问题标题】:Calculation of the number of microseconds in Ada计算 Ada 中的微秒数
【发布时间】:2022-04-05 15:32:17
【问题描述】:

在 C 语言中,我们有 get_usec() ,它为我们提供了自当前秒开始以来的微秒数。 - 说到“当前秒”必然是指时间参考,通常是 EpochTime。 -在 Ada.Calendar 包中,我通过示例看到 Seconds 或 Clocks 函数,它们具有拆分和获取秒数的能力。 但是如何获得自当前秒开始以来的微秒数,好吗? 谢谢 标记

【问题讨论】:

  • 我们在 C 中有 get_usec 吗?我在 C11 草案标准中找不到它,网络搜索也没有找到任何有希望的结果。

标签: real-time ada epoch milliseconds


【解决方案1】:

请注意,Ada.Calendar 是本地时间,可能会向后跳转。如果它可用(是否有任何不提供它的 83 后编译器?),您最好使用 Ada.Real_Time ARM D.8

Now : constant Ada.Real_Time.Time := Ada.Real_Time.Clock;

Count : Ada.Real_Time.Seconds_Count;
Sub   : Ada.Real_Time.Time_Span;
...
Ada.Real_Time.Split (T => Now, SC => Count, TS => Sub);

现在 Count 包含自纪元以来的整秒数,而 Sub 包含除 Count 之外的秒数。 Ada.Real_Time.To_Duration 将 Time_Span 转换为 Duration,允许您将其乘以 1E6 以获得微秒。

【讨论】:

  • 如果您使用的是 Ada2020 之前的编译器,您会发现很难以人类可读的格式输出 Time_Span 变量的值。
  • @JimRogers,您看到 Jeffrey 提到 Ada.Real_Time.To_Duration 的部分了吗?那是在 Ada95 中。
  • 我看到了 Ada.Real_Time.Duration,但我无法验证这是 Ada.Calendar 中定义的持续时间。 LRM 没有规定 Ada.Real_Time 依赖于 Ada.Calendar。我只看到了以下“建议将Calendar.Clock和Real_Time.Clock实现为相同时基的转换。”
  • Duration 是标准中声明的定点类型。 Ada.Calendar.Day_Duration 是 Duration 的子类型。
【解决方案2】:

包 Ada.Calendar 和 Ada.Calendar.Formatting 提供了您需要的信息。

with Ada.Text_IO;             use Ada.Text_IO;
with Ada.Calendar;            use Ada.Calendar;
with Ada.Calendar.Formatting; use Ada.Calendar.Formatting;

procedure Main is
   Now     : Time            := Clock;
   Seconds : Second_Duration := Sub_Second (Now);
begin
   Put_Line
     ("Sub seconds since current second: " &
        Second_Duration'Image (Seconds));
end Main;

该程序的一次执行的输出是:

自当前秒起的亚秒数:0.655316600

在此执行中,该值指示 655316.6 微秒。

【讨论】:

    【解决方案3】:

    它也可以(当然)在没有 Ada.Calendar.Formatting 的情况下完成,例如:

    with Ada.Calendar; use Ada.Calendar;
    ...
    type Seconds_In_Day is range 0 .. 86_400;
    -- Or use Integer if it is 32 bits.
    
    Now : constant Day_Duration := Seconds (Clock);
    Subsec : Duration := Now - Day_Duration (Seconds_In_Day (Now));
    ...
    if Subsec < 0.0 then
       -- Conversion of Now rounded up instead of down.
       Subsec := Subsec + 1.0;
    end if;
    

    结果在 Subsec 中。

    但据我所知,使用 Ada.Calendar.Formatting.Sub_Second 更短,并且可能更好(更快或更准确);我没有比较这两种方法。

    【讨论】:

      【解决方案4】:

      非常感谢您的回答。

      使用你所有的例子,我做了一些试验,一个如下:

      with Ada.Text_IO;   use Ada.Text_IO;
      
      with Ada.Calendar;  use Ada.Calendar;
      with Ada.Real_Time; use Ada.Real_Time;
      
      procedure Display_Current_Year is
      
         --need to precise the origin package Ada.Real-Time else ambiguous
         Now         : Ada.Calendar.Time := Clock;
         
         Now_Year    : Year_Number;
         Now_Month   : Month_Number;
         Now_Day     : Day_Number;
         Now_Seconds : Day_Duration;
         
         Current_Real_Time : Ada.Real_Time.Time;
         Time_Span         : Ada.Real_Time.Time_Span;
         Seconds_Count     : Ada.Real_Time.Seconds_Count;
         
         Hour : float;
            
      begin
      
         --- Ada.Calendar
         Split (Now,
                Now_Year,
                Now_Month,
                Now_Day,
                Now_Seconds);
                
         Put_Line("Calendar : Date du jour = ");
         Put_Line ("Current year  is: "
                   & Year_Number'Image (Now_Year));
         Put_Line ("Current month is: "
                   & Month_Number'Image (Now_Month));
         Put_Line ("Current day   is: "
                   & Day_Number'Image (Now_Day));
         Put_Line ("'Current' seconde   is: "
                   & Day_Duration'Image (Now_Seconds));
         New_Line;
      
         --Ada.Real_Time; 
         Current_Real_Time := Ada.Real_Time.Clock;
      
         Ada.Real_Time.Split (T  => Current_Real_Time,
                              Sc => Seconds_Count,
                              Ts => Time_Span);
      
         Put_Line ("Real_Time : Seconds_Count = " & Seconds_Count'Img);
         Hour := (float(Seconds_count) / 3600.00);
         Put_Line ("Hour since seconds origin : " 
                                           & (Hour'Img));
      
      end Display_Current_Year;
      
      with result :
      
      $ ./display_current_year
      Calendar : Date du jour = 
      Current year  is:  2022
      Current month is:  2
      Current day   is:  27
      'Current' seconde   is:  68625.325897000
      
      Real_Time : Seconds_Count =  30953
      Hour since seconds origin :  8.59806E+00
      $
      -Results for calendar are OK, but why 30953 seconds !!
      Where does GNAT take the Epoch, if this is, in this case, please?
      Thanks
      Mark
      

      【讨论】:

        【解决方案5】:

        你可以做一个肮脏的把戏,你定义一个记录 My_raw_duration_Type :whole_part,fraction_part,都是U32。定义 Unchecked_Conversion To_Raw (Ada.Real_Time.Duration, My_Raw_Duration_Type)。然后将其结果命名为 My_Raw_Duration。您想要的毫秒结果是 integer(float(My_Raw_Duration.Fraction_Part)/float(4*1032**2) * 1000.0);

        【讨论】:

        • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多