Board logo

标题: [数值计算] [已解决]批处理中set /a怎么利用移位判断正负? [打印本页]

作者: JooKin    时间: 2011-9-6 20:45     标题: [已解决]批处理中set /a怎么利用移位判断正负?

  1. set/a n=a">>"31
  2. ::a>0时,n=0,a<=0时,n=-1
复制代码
set/a 1">>"31
结果为0,是1/(2^31)这样算的是吧,
可是:
set/a -1">>"31
结果是-1,但是-1/2147483648的结果却是0,

就是不明白为什么不是-1?
作者: garyng    时间: 2011-9-6 21:36

回复 1# JooKin


    额~批处理可以做除法的咩? -1/2147483648很靠近0,批处理只能取整数部分而已,所以它只显示0咯~
作者: JooKin    时间: 2011-9-6 22:09

回复 2# garyng

可是-1">>"31的结果为什么会是-1呢?
作者: plp626    时间: 2011-9-6 22:32

回复 3# JooKin
  1. ->for /l %a in (-15 1 15)do d2b %a
  2. ->d2b -15
  3. 11111111111111111111111111110001
  4. ->d2b -14
  5. 11111111111111111111111111110010
  6. ->d2b -13
  7. 11111111111111111111111111110011
  8. ->d2b -12
  9. 11111111111111111111111111110100
  10. ->d2b -11
  11. 11111111111111111111111111110101
  12. ->d2b -10
  13. 11111111111111111111111111110110
  14. ->d2b -9
  15. 11111111111111111111111111110111
  16. ->d2b -8
  17. 11111111111111111111111111111000
  18. ->d2b -7
  19. 11111111111111111111111111111001
  20. ->d2b -6
  21. 11111111111111111111111111111010
  22. ->d2b -5
  23. 11111111111111111111111111111011
  24. ->d2b -4
  25. 11111111111111111111111111111100
  26. ->d2b -3
  27. 11111111111111111111111111111101
  28. ->d2b -2
  29. 11111111111111111111111111111110
  30. ->d2b -1
  31. 11111111111111111111111111111111
  32. ->d2b 0
  33. 00000000000000000000000000000000
  34. ->d2b 1
  35. 00000000000000000000000000000001
  36. ->d2b 2
  37. 00000000000000000000000000000010
  38. ->d2b 3
  39. 00000000000000000000000000000011
  40. ->d2b 4
  41. 00000000000000000000000000000100
  42. ->d2b 5
  43. 00000000000000000000000000000101
  44. ->d2b 6
  45. 00000000000000000000000000000110
  46. ->d2b 7
  47. 00000000000000000000000000000111
  48. ->d2b 8
  49. 00000000000000000000000000001000
  50. ->d2b 9
  51. 00000000000000000000000000001001
  52. ->d2b 10
  53. 00000000000000000000000000001010
  54. ->d2b 11
  55. 00000000000000000000000000001011
  56. ->d2b 12
  57. 00000000000000000000000000001100
  58. ->d2b 13
  59. 00000000000000000000000000001101
  60. ->d2b 14
  61. 00000000000000000000000000001110
  62. ->d2b 15
  63. 00000000000000000000000000001111
  64. ->
复制代码

作者: JooKin    时间: 2011-9-6 23:21

回复 4# plp626


    这个看不太明白,能解释下吗?
还有我记得以前在那本绿皮书上说过,当最高位为1的时候,右移的话,有的编译系统是左补0,有的是左补1,左补0的叫“逻辑移位”,左补1的叫“算术移位”
按这样说的话,CMD是左补0还是1?
作者: plp626    时间: 2011-9-6 23:33

本帖最后由 plp626 于 2011-9-6 23:34 编辑

回复 5# JooKin


    cmd的数字是有符号数,按理是算术移位
  1. ->d2b -1
  2. 11111111111111111111111111111111
  3. ->d2b 0
  4. 00000000000000000000000000000000
  5. ->d2b 1
  6. 00000000000000000000000000000001
复制代码

作者: JooKin    时间: 2011-9-7 01:50

回复 6# plp626


    谢谢,明白了!
比如-9>>31
11111111111111111111111111110111
>>31
------------------------------------------------------
11111111111111111111111111111111
反正只要是负数,右移31位,最低位一定是1,再全部左补1,就是-1了。
作者: JooKin    时间: 2011-9-7 01:55

可是-1>>31和-1/2147483647不是等价的吗?怎么结果会不一样?
作者: JooKin    时间: 2011-9-7 14:06

本帖最后由 JooKin 于 2011-9-7 16:26 编辑

没有大侠指点迷津吗?还是因为太简单了
作者: plp626    时间: 2011-9-7 23:59

回复 8# JooKin
  1. >> set/a 2147483647
  2. 2147483647
  3. >> set/a 2147483648
  4. -2147483648
  5. >> set/a 2147483649
  6. -2147483647
  7. >> set/a 4294967294
  8. -2
  9. >> set/a 4294967295
  10. -1
  11. >> d2b 2147483647
  12. 01111111111111111111111111111111
  13. >> d2b 2147483648
  14. 10000000000000000000000000000000
  15. >> d2b -2147483648
  16. 10000000000000000000000000000000
  17. >> d2b 2147483649
  18. 10000000000000000000000000000001
  19. >> d2b -2147483647
  20. 10000000000000000000000000000001
  21. >> d2b 4294967294
  22. 11111111111111111111111111111110
  23. >> d2b -2
  24. 11111111111111111111111111111110
  25. >> d2b 4294967295
  26. 11111111111111111111111111111111
  27. >> d2b -1
  28. 11111111111111111111111111111111
  29. >> set/a -1/4294967295
  30. 1
  31. >>
复制代码

作者: JooKin    时间: 2011-9-8 01:15

回复 10# plp626

d2b得出来的是原码吗?
  1. C:\Documents and Settings\Administrator>set/a 4294967294
  2. -2
  3. C:\Documents and Settings\Administrator>set/a 4294967295
  4. 无效数字。数字精确度限为 32 位。
  5. C:\Documents and Settings\Administrator>set/a -1/4294967295
  6. 无效数字。数字精确度限为 32 位。
复制代码
why?
作者: plp626    时间: 2011-9-8 11:41

回复 11# JooKin


那先用这个代码理解
  1. set/a -2/4294967294
复制代码
set/a 4294967295是阶段性罢工,原因未明,我这里有时也罢工,你再试试,
作者: JooKin    时间: 2011-9-8 16:19

回复 12# plp626


    能理解了,
set/a -1/2147483647就是(11111111111111111111111111111111)2÷(01111111111111111111111111111111)2的运算,除了符号位外,原来他们在内部存储的二进制形式都是一样的,所以运算结果就是-1了。
作者: plp626    时间: 2011-9-8 23:13

回复 13# JooKin
  1. ->set/a -1/2147483647
  2. 0
复制代码

作者: JooKin    时间: 2011-9-13 13:45

回复 14# plp626

有点乱|||!请问d2b得出来的是原码还是补码?
作者: plp626    时间: 2011-9-13 23:20

回复 15# JooKin
补码;
你别想复杂了,这是d2b的bat代码:
  1. :: d2b.cmd
  2. @call dec2x.cmd 2 32 %1 %2
  3. @if %2.==. echo %$%
复制代码
  1. :: dec2x.cmd
  2. @ECHO %#debug% off
  3. :d2x <进制=2 8 16> <多少位> <数字> <返回>
  4. SETLOCAL ENABLEDELAYEDEXPANSION
  5. set /a "p=%1-1,x=(p-1)/3+^!(%1&16),d=%3,lp=%2"
  6. set m=0123456789ABCDEF&set h=
  7. for /L %%: in (1,1,%lp%)do set/a"t=d&p,d>>=x"&Set h=$m:~!t!,1$!h!
  8. for %%a in ("%h:$=!%")do endlocal&Set $%4=%%~a
复制代码
附带两个外部命令:
  1. :: d2h.cmd
  2. @call dec2x 16 8 %1 %2
  3. @if %2.==. echo %$%
复制代码
  1. :: d2o.cmd
  2. @call dec2x 8 11 %1 %2
  3. @if %2.==. echo %$%
复制代码

作者: JooKin    时间: 2011-9-18 14:44

回复 16# plp626


    看不太懂




欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2