首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >?一般情况下和特指德尔菲中双倍的解剖

问?一般情况下和特指德尔菲中双倍的解剖
EN

Stack Overflow用户
提问于 2013-11-29 18:50:14
回答 2查看 370关注 0票数 0

据维基百科( Wikipedia )报道,我知道双打有一个符号(1位)、指数(11位)和分数(52位)。

我有三个问题。

1)如何使用这三个部分将它们转换为我可以使用的数字(包括整数部分和分数部分)?

( 2)在Delphi中,这三个部分是如何存储在一个双重中的?

3)一旦我知道了积分部分和分数部分,我就把它们作为日期和时间使用,从午夜开始,日期就是偏移量,小数部分是偏移量,我认为是毫秒。所以这两个数字,我试着从双,天和毫秒中推导出来。问题是,有没有办法把这两者分离成国家统计局?也就是说,使用标准的数学函数将日偏移到int (或using int ),将毫秒偏移到另一个int(或using int)?

我早些时候发现,我存储的日期的十六进制表示确实是Delphi的双倍(见下文)。但我不知道这两个人是怎么表现出来的

实际上,这些字符串看起来像Delphi TDatetime类型的十六进制表示,它是双类型(8个字节)的别名,其中TDateTime值的整体部分是自1899年12/30/1899以来已经过去的天数,而TDateTime值的小数部分是已经过去的24小时的小数。

在Delphi中,可以使用HexToBin函数解析这些值,如下所示

代码语言:javascript
复制
{$APPTYPE CONSOLE}

uses
  System.Classes,
  System.SysUtils;

function Decode(const HexStr: AnsiString) : TDateTime;
begin
   Assert(Length(HexStr)=16, 'Lenght must be 16');
   HexToBin(PAnsiChar(HexStr), @Result, SizeOf(TDateTime));
end;

begin
  try
     Writeln(DateTimeToStr(Decode('a297780add3ee440')));
     Writeln(DateTimeToStr(Decode('5c6c320bdd3ee440')));
     Writeln(DateTimeToStr(Decode('67b176e0dd3ee440')));
     Writeln(DateTimeToStr(Decode('38a7e155bc42e440')));
     Writeln(DateTimeToStr(Decode('d94ee458bc42e440')));
     Writeln(DateTimeToStr(Decode('d22af9134989dc40')));
     Writeln(DateTimeToStr(Decode('d4fb7863c542e440')));
     Writeln(DateTimeToStr(Decode('e501c962c542e440')));
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  ReadLn;
end.

这个会回来的

代码语言:javascript
复制
07-07-2013 21:46:50
07-07-2013 21:46:58
07-07-2013 22:24:27
07-08-2013 21:15:05
07-08-2013 21:15:37
01-01-1980 3:24:15
08-08-2013 4:02:29
08-08-2013 4:02:21
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-11-29 19:02:11

Delphi值是使用标准表示形式的标准IEEE754双值。由于各种原因,所有语言都会这样做。其中最重要的是底层硬件操作为IEEE754类型。

您可以使用在TDoubleHelper中引入的XE3来提取一个双值。文档向您展示了如何实现:http://docwiki.embarcadero.com/Libraries/en/System.TDoubleHelper。对于较早的Delphi版本,您可以改用TDoubleRec。

现在,将值分解为它的意义和指数对您没有任何帮助。你想要整数部分和分数部分,它们是完全不同的东西。让他们使用标准函数Int()和Frac()。

然而,当你这样做的时候,你仍然得不到你所需要的。小数部分是0到1之间的浮点数,听起来不太像毫秒数。所以我相信你们还没有完全理解这个表述。

也许你所拥有的不过是一个TDateTime!在这种情况下,您可以使用RTL中的标准函数对其进行解码。

我刚读了你之前的问题。你确实走错了轨道。再读一遍答案。具体地说:

其中,TDateTime值的整体部分是自1899年12月30日以来已经过去的天数,而TDateTime值的小数部分是已经过去的24小时一天的一部分。

因此,在您的VB代码中,将十六进制字符串或二进制,无论您有什么,转换成一个双。然后得到整数部分和小数部分,你就完成了。

票数 1
EN

Stack Overflow用户

发布于 2013-11-29 19:15:24

您误解了TDateTime的相关部分所包含的内容。

积分部分(小数点左边的部分)是自1899年12月30日以来已经过去的天数,如您所述。然而,小数部分(小数点右边的部分)只是00:00:00 0001 (当天的开始)以来时间的小数表示。

换句话说,

代码语言:javascript
复制
0.25          12/30/1899 06:00:00 (6:00 AM)
0.5           12/30/1899 12:00:00 (noon)
0.75          12/30/1899 18:00:00 (6:00 PM)

使用德尔福的TDateTime和它的各个部分的最简单方法是让RTL为您处理它。若要分离时间的各个部分,请使用DecodeTime。要检索日期的各个部分,请使用DecodeDate (都来自“SysUtils”单元):

代码语言:javascript
复制
var
  Hr, Min, Sec: Word;
  Yr, Mon, Day: Word;  

  DecodeTime(Now, Hr, Min, Sec);
  DecodeDate(Now, Yr, Mon, Day);

要同时检索它们,请使用DateUtils单元和DecodeDateTime:

代码语言:javascript
复制
  DecodeDateTime(Now, Yr, Mon, Day, Hr, Min, Sec);

如果你真的只想要小数点的各个部分(小数点的左边和右边),那么就像大卫说的,你只需要使用Int和Frac。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20291808

复制
相关文章

相似问题

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