Board logo

Subject: 请教大家一个问题,不好描述,看看源码说话吧 [Print This Page]

Author: Redbreast    Time: 2009-6-30 17:07     Subject: 请教大家一个问题,不好描述,看看源码说话吧

function IntToBin(Value: Byte): string;overload;
var
  i: Integer;
begin
  SetLength(result, 8);
  for i := 1 to 8 do
  begin
    if ((Value shl (i - 1)) shr 7) = 0 then
      result[ i ] := '0'
    else
      result[ i ] := '1';
  end;
end;

function IntToBin(Value: Byte): string;overload;
var
  i: Integer;
  tmpByte : Byte;
begin
  SetLength(result, 8);
  for i := 1 to 8 do
  begin
    tmpByte := Value shl (i - 1);
    tmpByte := tmpByte shr 7;
    if tmpByte = 0 then
      result[ i ] := '0'
    else
      result[ i ] := '1';
  end;
end;

输入4,前一个输出:00000111,后一个输出00000100,哪位大侠给指导一下原因?

d7和d2007好像都是这样!

[ 本帖最后由 Redbreast 于 2009-6-30 17:22 编辑 ]
Author: Passion    Time: 2009-6-30 17:23

问题是否是问第一个为啥错了?
Author: wqyfavor    Time: 2009-6-30 18:52

Value shl (i - 1)) shr 7以Integer类型做为中间结果,所以i=8时左移7位再右移7位相当于没移,当然出来1了。
第二个用Byte类型保存中间值是正确的算法。位操作还是要小心。
Author: Redbreast    Time: 2009-6-30 21:28

确实我是想问为何第一个结果不对
byte只是一个例子而已,word,cardinal也是如此.所以楼上以Integer类型做为中间结果的说法似乎并非原因所在,各位可以测试一下...

[ 本帖最後由 Redbreast 於 2009-6-30 21:43 編輯 ]
Author: wqyfavor    Time: 2009-6-30 22:31

晕了,Cardinal和Integer是一样的,另外Word是占用两个字节的,汇编代码里使用的是AX寄存器,同样会导致左移7位再右移7位不变的情况。使用Byte类型的话是使用的AL寄存器的,左移7位那个1会被移出去的。你设置一下断点,然后进cpu窗口就全明白了。

[ 本帖最后由 wqyfavor 于 2009-6-30 22:33 编辑 ]
Author: Redbreast    Time: 2009-7-1 07:11

但是Cardinal也是同这样,只要出现一个1,后面跟着的全是1阿
家里没有IDE测试,明后天我去单位看一下...
Author: Redbreast    Time: 2009-7-22 17:05

最近比较忙,没有整这个问题
先谢谢wqyfavor 的回复

前一段时间我好像测试了Cardinal也不对,所以以为是别的问题,今天看了一下汇编和寄存器,果然如wqyfavor 所说!




Welcome to CnPack Forum (http://bbs.cnpack.org/) Powered by Discuz! 5.0.0