[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[数值计算] 【已解决】批处理的整数变量是如何解析存储的?

本帖最后由 buyiyang 于 2023-9-26 09:18 编辑

批处理数字精度是32位,如果是补码存储,为什么会出现这种情况?
  1. set /a n=-2147483648
  2. 无效数字。数字精确度限为 32 位。
复制代码
无法输入-2147483648,但却可以计算输出,
  1. set /a n=-2147483647-1
  2. set /a n=2147483647+1
复制代码
都可以为变量n赋值为-2147483648,问题是为什么set /a n=-2147483648不能实现赋值?
1

评分人数

    • Batcher: 感谢给帖子标题标注[已解决]字样PB + 2

回复 6# Five66


    计算机算的是补码,10000000  00000000  00000000  00000000是-2147483648的补码而不是原码。

TOP

回复 3# 老刘1号

可能吧,我看了操作正数和负数的内存,似乎有点不同,但我不懂汇编。
set /a n=2147483647
  1. jae 00000067
  2. je 00000024
  3. das
  4. popad
  5. and [esi+3D],ch
  6. xor dh,[ecx]
  7. xor al,37
  8. xor al,38
  9. xor esi,[esi]
  10. xor al,37
复制代码
set /a n=-2147483647
  1. jae 00000067
  2. je 00000024
  3. das
  4. popad
  5. and [esi+3D],ch
  6. sub eax,37343132
  7. xor al,38
  8. xor esi,[esi]
  9. xor al,37
复制代码

TOP

回复 2# hlzj88


    set n=-2147483648确实可以,然后可以操作set /a n=n+1,但我想问的是set n=-2147483648为什么不行。

TOP

本帖最后由 buyiyang 于 2023-9-25 19:15 编辑

回复 12# 老刘1号


    大概明白了,算数运算的解析字符串表达式是逐字符的,-首先被解析,被解析为操作符了,然后后面的数字2147483648被解析为操作数,操作数字符串要转长整型,过程中由于溢出遇到错误tas会指向最后停止的位置,判断指向的是数字8就会报错。

    十分感谢@老刘1号提供的源码!基于第二个源码我再详细理解一下解析过程,有几个重要的变量,bUnaryOpPossible来判断是否允许一元操作符出现,初始值为TRUE。然后c=*tas,c是TCHAR类型的,c那么就是tas字符串数组的第一个字符,然后判断c是空白、字母、数字、操作符还是变量名,空白字符删除,操作符压入操作符栈,变量名压入操作数栈,变量名存储在 lOperands 数组中的Name字段,计算表达式时从环境变量中获取其值,如果是数字就从对tas字符串进行_tcstol处理转成长整型,遇到错误就将指针指向最后停止的位置,去除tas字符串前面成功转成长整型的部分。每判断一个字符,都会tas += 1,去除tas字符串中前一个已经判断过的字符。进行do while循环中直到尾tas字符串\0。

    比如,set /a n=1+1,对于字符串"n=11+1",首先指针指向n,c为'n',判断为变量名,然后指针移到=,判断为操作符,指针移到1,判断为数字,对"11+1"进行_tcstol处理,在+遇到错误,11转成长整型作为操作数,指针移到+,判断为操作符,指针移到1,判断为数字,对"1"进行_tcstol处理,1转成长整型作为操作数,指针移到\0,循环结束。

TOP

回复 15# 老刘1号
进行_tcstol的时候c已经是一个dight了,而c=*tas,那么也就是说tas指向的字符串是数字开头的

这个是如何看出来的?

TOP

回复 20# 老刘1号


    这里从tas字符数组第一个地址开始判断每个字符是空白、字母、数字、操作符,如何得出tas指向的字符串是数字开头的?do循环中,c=*tas应该是tas字符数组的第一个字符,判断完后,然后tas += 1,再赋值c=*tas是tas字符数组的第二个字符。

TOP

回复 22# 老刘1号


    可能误解你的意思了,你的意思是:c=*tas,当能进行_tcstol的时候说明c是一个dight,此时tas指向的字符串是数字开头的。明白了,我以为你说一开始的tas

TOP

返回列表