China DOS Union

-- Unite DOS · Advance DOS · Grow DOS --

Union site: www.cn-dos.net Forum site: www.cn-dos.net/forum
DOS stands for freedom, openness and progress. Let us work hard, learn from the openness and GNU spirit of FreeDOS and Linux, and together build and grow a free GNU GPL world!

中国DOS联盟论坛
The time now is 2026-06-20 14:35
中国DOS联盟论坛 » DOS批处理 & 脚本技术(批处理室) » [Joint Participation] [Challenge Ideas] [Batch Processing Floating-Point Operations] DigestI View 41,150 Replies 136
Floor 16 Posted 2006-10-05 05:22 ·  中国 湖南 娄底 电信
银牌会员
★★★
Credits 1,218
Posts 485
Joined 2006-07-21 21:24
19-year member
UID 58987
From 湖南.娄底
Status Offline
The code on the 10th floor has been updated; it can remove multiple zeros at the highest digit. Please test...
Floor 17 Posted 2006-10-05 05:37 ·  中国 四川 南充 电信
超级版主
★★★★
我爱DOS
Credits 5,310
Posts 2,044
Joined 2005-09-26 12:00
20-year member
UID 42843
Gender Male
From 四川南充
Status Offline
Floor 18 Posted 2006-10-05 05:59 ·  中国 四川 南充 电信
超级版主
★★★★
我爱DOS
Credits 5,310
Posts 2,044
Joined 2005-09-26 12:00
20-year member
UID 42843
Gender Male
From 四川南充
Status Offline
The code on the 15th floor has been updated; it can remove multiple zeros at the highest digit and accepts decimals like .98! Please test...
Recent Ratings for This Post ( 1 in total) Click for details
RaterScoreTime
+6 2006-10-20 20:19
Floor 19 Posted 2006-10-05 06:53 ·  中国 浙江 宁波 鹏博士宽带
荣誉版主
★★★
Credits 1,338
Posts 356
Joined 2005-07-15 12:09
20-year member
UID 40733
Gender Male
Status Offline
I personally very much agree with this kind of discussion method. Everyone can discuss more detailed judging and reward methods.
I am also submitting a roll. I simulated the manual calculation process, mainly wanting to practice character handling; the writing process was quite strenuous, and execution efficiency is not high either. It supports various complex formats of two numbers, and the number length is unrestricted, only it will be very slow.


  1. @echo off
  2. setlocal
  3. set number1=%~1
  4. set number2=%~2
  5. if "%number1%" == "" goto :EOF
  6. if "%number2%" == "" set number2=0
  7. set D1=0
  8. set D2=0
  9. set flag=0
  10. set D1=%number1:*.=%
  11. call set I1=%%number1:.%D1%=%%
  12. set D2=%number2:*.=%
  13. call set I2=%%number2:.%D2%=%%

  14. if "%D1%" == "%number1%" set D1=0
  15. if "%D2%" == "%number2%" set D2=0
  16. set D1=1%D1%
  17. set D2=1%D2%
  18. call :fill %D1% %D2% D1 D2
  19. call :sum $%D1% $%D2%
  20. if "%sum:~0,1%" GTR "2" set /a flag=1
  21. set D_sum=%sum:~1%
  22. call :sum $%I1% $%I2%
  23. set I_sum=%sum%
  24. echo %number1% + %number2% =
  25. if %D_sum% EQU 0 (
  26. echo. %I_sum%
  27. ) else (
  28. echo. %I_sum%.%D_sum%
  29. )
  30. goto :EOF

  31. :sum
  32. set sum=
  33. set temp1=%1
  34. set temp2=%2
  35. if "%flag%" == "1" set H=1
  36. set n=1
  37. :next
  38. call set x=%%temp1:~-%n%,1%%
  39. call set y=%%temp2:~-%n%,1%%
  40. if "%x%" == "$" (
  41. if "%y%" == "$" (
  42. if "%H%" GTR "0" set sum=%H%%sum%
  43. goto :EOF
  44. ))
  45. if "%x%" == "$" set x=0
  46. if "%y%" == "$" set y=0
  47. call :sub %x% %y% %H%
  48. set sum=%ERRORLEVEL%%sum%
  49. set /a n+=1
  50. goto next

  51. :sub
  52. set H=0
  53. if "%1" == "" exit /b 0
  54. if "%2" == "" exit /b %1
  55. if "%3" == "" call :sub %1 %2 0 &goto :EOF
  56. set /a s=%1 + %2 + %3
  57. set H=%s:~0,-1%
  58. set L=%s:~-1%
  59. exit /b %L%
  60. goto :EOF

  61. :fill
  62. setlocal
  63. set n=-1
  64. set temp1=%1
  65. set temp2=%2
  66. :loop
  67. set /a n+=1
  68. call set x=%%temp1:~%n%,1%%
  69. call set y=%%temp2:~%n%,1%%
  70. if "%x%" == "" (
  71. if "%y%" == "" (
  72. endlocal &set %3=%temp1% &set %4=%temp2%
  73. goto :EOF
  74. ))
  75. if "%x%" == "" set temp1=%temp1%0
  76. if "%y%" == "" set temp2=%temp2%0
  77. goto :loop
  78. goto :EOF
Posted by 无奈何 2006-10-04 18:56


Test code:

call sum %RANDOM%
call sum %RANDOM% %RANDOM%
call sum .%RANDOM% %RANDOM%
call sum %RANDOM% .%RANDOM%
call sum %RANDOM%.%RANDOM% %RANDOM%
call sum %RANDOM% %RANDOM%.%RANDOM%
call sum %RANDOM%.%RANDOM% %RANDOM%.%RANDOM%
call sum %RANDOM%%RANDOM%%RANDOM%%RANDOM%%RANDOM% %RANDOM%%RANDOM%%RANDOM%%RANDOM%%RANDOM%%RANDOM%%RANDOM%
pause


[ Last edited by 无奈何 on 2006-10-5 at 07:01 ]
  ☆开始\运行 (WIN+R)☆
%ComSpec% /cset,=何奈无── 。何奈可无是原,事奈无做人奈无&for,/l,%i,in,(22,-1,0)do,@call,set/p= %,:~%i,1%<nul&ping/n 1 127.1>nul

Floor 20 Posted 2006-10-05 07:37 ·  中国 北京 联通
金牌会员
★★★★
Credits 2,902
Posts 1,147
Joined 2006-09-21 12:00
19-year member
UID 63324
Gender Male
Status Offline
This test calculation method that generates random numbers is very interesting~~~~~ :)
Floor 21 Posted 2006-10-05 07:45 ·  中国 北京 联通
金牌会员
★★★★
Credits 2,902
Posts 1,147
Joined 2006-09-21 12:00
19-year member
UID 63324
Gender Male
Status Offline
Originally posted by pengfei at 2006-10-4 23:50:
Solved the problem where the first digit after the decimal point is 0 and an 8 or 9 appears after it, causing the value to be an invalid number.

A brand-new algorithm; the rough idea is: read the decimal digit count and pad zeros where insufficient. After removing the . sign, decimal and inte ...



(two floating-point numbers to be calculated)
1932.00010002 (decimal length 8)
19.02310

(remove the decimal point, align to the longest decimal part, pad 0 where digits are insufficient)
193200010002
1902310000
---------------------------
Sum: 195102320002

1951.02320002
(using the longest decimal digit count before merging as the base, move the decimal point left to complete the floating-point calculation)

(another kind)
(or calculate the integer parts of n floating-point numbers, calculate the decimal parts of n floating-point numbers, and carry by the longest)
(remove zeros on the left of floating-point numbers completely)

Same as the way I was thinking~ :)
Pad insufficient places with 0, then treat the floating-point number as an integer and calculate it with another floating-point number treated as an integer (remove the point),
finally move the decimal point left :)

Excited~ :)
Besides being excited, there is a bit of helplessness. It seems that there are extremely few netizens who really want to master batch files;
netizens who like fun algorithms and batch files that are like writing code are comparatively very few;
most netizens think of batch files when they need to use them, and when they don’t need them, they are dispensable……

[ Last edited by redtek on 2006-10-5 at 08:01 ]
Floor 22 Posted 2006-10-05 08:37 ·  中国 湖南 娄底 新化县 电信
银牌会员
★★★
Credits 1,218
Posts 485
Joined 2006-07-21 21:24
19-year member
UID 58987
From 湖南.娄底
Status Offline
Hehe~ Moderator qwe1234567 really is attentive; even the testing is so comprehensive.

The code has been updated on the 10th floor! It can remove multiple zeros at the highest digit. The defects raised by everyone before have all been solved. Current testing is all normal; looking forward to experts finding more defects. Only through exchange can there be progress... ^_^
Floor 23 Posted 2006-10-05 08:50 ·  中国 湖南 娄底 新化县 电信
银牌会员
★★★
Credits 1,218
Posts 485
Joined 2006-07-21 21:24
19-year member
UID 58987
From 湖南.娄底
Status Offline
I just tested the code on the 15th floor; there are still defects, such as (00.85 12.871) (00.42 13.89), etc.

The multiple leading zeros removal the moderator mentioned seems not to work. Also, if two or more zeros appear at the very front of the integer, the calculation will error.
Floor 24 Posted 2006-10-05 10:08 ·  中国 广东 佛山 广东睿江科技有限公司
荣誉版主
★★★★
batch fan
Credits 5,226
Posts 1,737
Joined 2006-03-10 00:38
20-year member
UID 51697
From 成都
Status Offline
  So far, everyone has already found two methods for calculating floating-point numbers under CMD:

  Method one: Calculate the integer part and decimal part of the floating-point number separately. The implementation process is: the integer parts can just be added directly; the decimal part is a little troublesome: if the decimal part digit counts are inconsistent, use the number with the most digits as the basis, pad the decimal part of the other number with enough 0s, then do integer addition on the decimal parts; if the digit length of the addition result exceeds the longest digit count, carry 1 into the integer part, and correspondingly subtract 1 from the highest digit of the decimal part;

  Method two: Recombine the integer part and decimal part into a new number, perform addition on the new number, and finally insert the decimal point back into the original position;

  The respective advantages and disadvantages of the two methods:

  Method one: Advantage: it can handle a very large range of floating-point numbers; as long as the addition result is between (2^32-1.2^32-1) and -(2^32-1.2^32-1), it can handle it; disadvantage: most problems occur in the decimal part, for example: if the highest digit of the decimal part is 08 or 09, errors may occur, and these two cases need separate handling; if the digit length of the decimal part’s addition result exceeds the longest digit count, the integer part must be incremented by 1 and the highest decimal digit decremented by 1; if extended to addition of three or more floating-point numbers, the carry problem will become even more complex;

  Method two: Advantage: There is no need to separately handle the 08 and 09 cases, and no need to consider the carry problem (after reading pengfei’s analysis downstairs, I found that the description here has a bit of a problem; for details please refer to the description downstairs); disadvantage: the range of floating-point numbers it can handle is relatively small. It can only succeed when the new value after removing the decimal point from the addition result is between (2^32-1.2^32-1) and -(2^32-1.2^32-1).

  The above is my little bit of shallow understanding. Some places may not be very correct; everyone is welcome to discuss together.

[ Last edited by namejm on 2006-10-5 at 10:45 ]
Recent Ratings for This Post ( 1 in total) Click for details
RaterScoreTime
xycoordinate +1 2007-03-04 23:16
尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。
Floor 25 Posted 2006-10-05 10:14 ·  中国 湖南 娄底 新化县 电信
银牌会员
★★★
Credits 1,218
Posts 485
Joined 2006-07-21 21:24
19-year member
UID 58987
From 湖南.娄底
Status Offline
Haha~ Solved another difficult problem.

For example, before this, the code on the 10th floor calculated (0.0+0.48). Here, according to the calculation principle of the code, the final calculation is (000+048), obviously a radix error. Here I used removal of the integer zero digit, only doing calculation on the decimal digits.

When solving the problem of the integer ones digit being zero, another problem appeared: (0.5+0.082), the final calculation is (500+082). Hehe~ The integer zero was just removed, and the zero in the decimal part appeared again; still an invalid number. Dizzy...

Previously, to solve the above problem, I assigned 1 to both integer ones digits. Although it can solve the problem when both ones digits are zero, if one of the operands’ ones digit is nonzero and the other is nonzero, this method will not work.

Now I use assigning a value of 1 when one operand’s ones digit is zero. If both are zero, assign 1 to both. Then the count variable correspondingly adds 1. Finally, when processing the calculation result, when processing to the ones digit, correspondingly subtract the count value. This solves this radix problem!

Current testing has not found any problem for the time being! The code has been updated on the 10th floor~~~!

[ Last edited by pengfei on 2006-10-5 at 22:31 ]
Floor 26 Posted 2006-10-05 10:40 ·  中国 湖南 娄底 新化县 电信
银牌会员
★★★
Credits 1,218
Posts 485
Joined 2006-07-21 21:24
19-year member
UID 58987
From 湖南.娄底
Status Offline
Moderator 无奈何’s code on the “19th floor” is so strong~~~!
Floor 27 Posted 2006-10-05 10:42 ·  中国 浙江 宁波 鹏博士宽带
荣誉版主
★★★
Credits 1,338
Posts 356
Joined 2005-07-15 12:09
20-year member
UID 40733
Gender Male
Status Offline
A simple method for calculating leading zeros in the floating-point part or integer part is: add 1 to the very front of the number; after calculation, judge whether the frontmost digit is 2. If so, remove the frontmost digit; if not, also remove the frontmost digit and add 1 to the frontmost digit.
The floating-point digits need to be padded with zeros to align.

[ Last edited by 无奈何 on 2006-10-5 at 10:45 ]
  ☆开始\运行 (WIN+R)☆
%ComSpec% /cset,=何奈无── 。何奈可无是原,事奈无做人奈无&for,/l,%i,in,(22,-1,0)do,@call,set/p= %,:~%i,1%<nul&ping/n 1 127.1>nul

Floor 28 Posted 2006-10-05 10:44 ·  中国 湖南 娄底 新化县 电信
银牌会员
★★★
Credits 1,218
Posts 485
Joined 2006-07-21 21:24
19-year member
UID 58987
From 湖南.娄底
Status Offline
Hehe~ This is exactly the method I used to implement it.
Floor 29 Posted 2006-10-05 23:58 ·  中国 四川 南充 电信
超级版主
★★★★
我爱DOS
Credits 5,310
Posts 2,044
Joined 2005-09-26 12:00
20-year member
UID 42843
Gender Male
From 四川南充
Status Offline
The code on the 15th floor has been updated; it can remove multiple zeros at the highest digit and accepts decimals like .98! Please test...
Floor 30 Posted 2006-10-06 00:12 ·  中国 湖南 娄底 新化县 电信
银牌会员
★★★
Credits 1,218
Posts 485
Joined 2006-07-21 21:24
19-year member
UID 58987
From 湖南.娄底
Status Offline
About the integer/floating-point segmented calculation code:

The code has been updated on the 4th floor~~~! It solves the radix error that may occur when the first digit of the decimal part is zero. Current testing can adapt to various different situations.

Below is a comparison of the calculation ranges of the code on the 4th floor and the 10th floor:

Integer/floating-point segmented calculation code: (For code, please see the 4th floor)
The integer part can calculate up to 9 digits, and the decimal part can calculate up to 8 digits.
The decimal part and integer part together can calculate up to 17 digits.
Otherwise it will overflow or be an invalid number...

Integer/floating-point merged calculation code: (For code, please see the 10th floor)
The integer part can calculate up to 8 digits, and the decimal part can calculate up to 8 digits.
The decimal part and integer part together can calculate up to 9 digits
Otherwise it will overflow or be an invalid number...


Everyone is welcome to test...

[ Last edited by pengfei on 2006-10-6 at 03:50 ]
Forum Jump: