转换整数到二进制文件-如何在 android 系统 (vs Windows)-做 XE5

标签: Android windows
发布时间: 2014/2/1 21:20:05
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

所以,昨天我打开了一个关于转换为二进制整数的问题,是不是对我来说有点清楚它的工作原理 (带移位运算)。现在论到这里的另一个问题: 它如何完成关于 android,为什么它会导致比在 windows 中,和如何获得的实际的二进制结果的机会,而不是得到现在什么干它以不同的方式 (和关于这一我不是尚未明确是什么 ; 它是某种程度上与错误值十六进制)。

我有此代码在 firemonkey 移动项目中,有两个,android 和 windows 平台设置为目标。这种方式的代码测试可以通过针对 windows,以便它编译速度更快,并预览作为虚拟移动窗体 ;好吧,至少,意图是要这样做,但看上去不是那么可靠的错误来源......

虽然在 Win32 很好的工作上运行相同的项目,android 结果中没有得到一个函数二进制结果上运行它。

我使用此代码来进行转换:

function IntToBin(Value: Integer): string;
var
  i: Integer;
begin
  SetLength(Result, 9);
  for i := 1 to 9 do begin
    if (Value shr (9-i)) and 1 = 0 then begin
      Result[i] := '0'
    end else begin
      Result[i] := '1';
    end;
  end;
end;

调试器显示这,试图转换值"1"时:

Result: 0x6d09d738
   *Result: #0'00000000'                      [expanded from Result]
Value: 1

现在,我知道原因我然后 (后的主要过程,调用此转换函数的完成) 取值的它应该确切地半 (1 而不是 3,而不是 4,第 2 8 isntead 的 16,6 而不是 12...) 是因为在 * 结果有清楚它是只有 8 位,当我需要 9 位结果 (我做从整数 (1..512) 转换为二进制......)和欧洲工商管理学院的阅读作为 0010 2,因此我拿 001,是 1,(0110) 我得到的不是 6 3 (011)、 8 (1000) 我得到 4 (100) 等......

现在我真的很想知道为什么,起初,它甚至会引发结果作为 0x6d09d738 / 0x6d09d738 而不是只是二进制文件,和为什么不 9 位,是它为我设置的结果字符串的长度?

此外,这里是另一个有趣和为我 ununderstandable 件:

这是我的程序,会触发转换:

procedure TForm1.CalculateAddress1;
var SetDip: string;
    C: integer;
begin
  SetDip := IntToBin(StrToInt(MergeAddr));
  //Text1.Text:=SetDip;
  for C := 1 to 9 do
    begin
      if Copy(SetDip, b, 1) = '1' then
      DipSW[10-b].IsChecked:=True
      else DipSW[10-b].IsChecked:=False;
    end;
end;

/ / (我使用这将 dmx 地址转化为 dip 开关配置......)

SetDip 获取价值像 #0 的东西 '00000000'。(它与不同 ; 这是案件时被转换的整数是 1 ; 11 我得到的 #0 '00000101') ;

这结果作为有一半的精确值,当它应该是 (我上文所述 ;我明白为什么会这样,因为一个结果的一位是缺掉......)。

但是,如果删除 / / 从 Text1.Text:=SetDip; ,其中准备了发言稿那里所以我可以在手机屏幕上看到结果,我接通下一个错误,电话只 !(再次,针对 windows 运行确定):

' 字符串索引超出范围 (-1)。必须是 > = 0 和 < = 8';

之后,引发故障的分割、 2 出现访问冲突错误和最后,这款应用程序关闭本身。

看起来它不能将 SetDip 复制到 Text1.Text 字段 ;这是我的想法。但后来我发现发生此错误并不总是,这是很奇怪,因为它应该并不只是: 它应该甚至离开 Text1.Text:=SetDip 放在代码 ;-> 不知怎么它 copyes 的字符串索引 9,如果不是多长时间 ;这是确切的原因它将引发错误,但是再说一遍: 为什么不总是吗?

[[Ps: +,发现自动,固定数组,Firemonkey 句柄,如果代码尝试创建条目超过定义大小。有趣的......:)这也许意味着它处理字符串长度和复制索引本身太......吗?]]

解决方法 1:

Android (和其他手机平台),在一个字符串中的第一个字符被索引值为 0,而在桌面版本中,它被索引值 1。

所以,您需要更改

Result[i] := '0'

Result[i-1] := '0'

当编译的移动平台。以自动执行此操作,您可以使用以下方法:

{$IFDEF CPUARM }
  Result[i-1] := '0'
{$ELSE }
  Result[i] := '0'
{$ENDIF }

但要小心它只索引 (ie.使用 [] 语法) 这就是不同。副本、 Pos 等功能仍将 1 视为在一个字符串中的第一个字符。

谈一谈不一致 (和一个程序员头痛)......

我使用了以下的 helper 函数:

FUNCTION GetChar(CONST S : STRING ; OneBasedIndex : Cardinal) : CHAR;
  BEGIN
    IF LOW(STRING)=0 THEN Result:=S[PRED(OneBasedIndex)] ELSE Result:=S[OneBasedIndex]
  END;

PROCEDURE SetChar(VAR S : STRING ; OneBasedIndex : Cardinal ; C : CHAR);
  BEGIN
    IF LOW(STRING)=0 THEN S[PRED(OneBasedIndex)]:=C ELSE S[OneBasedIndex]:=C
  END;

用于获取/设置一个字符,而不考虑编译目标。它还具有的优点是"经得起未来考验",因为它不使用编译器的 {$DEFINE} s,但检查的字符串类型的低指数。

赞助商