CnPack Forum » 技术板块灌水区 » 请教大家一个问题,不好描述,看看源码说话吧


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

[size=3]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,哪位大侠给指导一下原因?[/size]
[size=3]d7和d2007好像都是这样![/size]

[[i] 本帖最后由 Redbreast 于 2009-6-30 17:22 编辑 [/i]]

2009-6-30 17:23 Passion
问题是否是问第一个为啥错了?

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

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

[[i] 本帖最後由 Redbreast 於 2009-6-30 21:43 編輯 [/i]]

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

[[i] 本帖最后由 wqyfavor 于 2009-6-30 22:33 编辑 [/i]]

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

2009-7-22 17:05 Redbreast
最近比较忙,没有整这个问题
先谢谢wqyfavor 的回复

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

页: [1]


Powered by Discuz! Archiver 5.0.0  © 2001-2006 Comsenz Inc.