Batch Calcs ..与往常不一样

时间:2015-08-01 01:10:41

标签: batch-file

我尝试制作桌面二进制计算器,但似乎无法正确计算值。

http://pastebin.com/embed_js.php?i=mtsJRys8

:: functions for 128
if userValue GEQ 128 (
    set bin128 = 1
    goto 64
)
if not userValue GEQ 128 (
    set bin128 = 0
)

尝试获取变量' bin128'以值1或0结束

2 个答案:

答案 0 :(得分:3)

十进制到二进制转换器?

我在您的粘贴中看到您通过比较输入的数字和2的幂来计算二进制结果。有一个more efficient algorithm用于将dec转换为bin,它将处理0到2147483647之间的数字。

@echo off
setlocal

if "%~1"=="" (
    echo usage: %~nx0 integer
    goto :EOF
)

set /a dec = %~1

:/2
set /a mod = dec %% 2, dec /= 2
set "bin=%mod%%bin%"
if %dec% gtr 0 goto :/2

echo %bin%

我也看到paulsm4的评论推荐另一个(可疑报价)"真实"语言。但是,实际上,不计算已经具有直接的int-to-bin转换方法的语言,批处理脚本语言实际上可以节省几个步骤,因为所有数学都是整数数学,其中小数固有地被截​​断。这使您不必在每次迭代时都必须Math.floor或类似。这是批处理比其他语言更适合任务的一种情况。

如果您更喜欢使用二次幂比较方法,那么这是另一种解决方案。无论您提供的数字长度如何,它都会循环31次,但for /L非常有效。对于许多迭代,这实际上可能比上面的方法更快。不确定。

@echo off
setlocal enabledelayedexpansion

if "%~1"=="" (
    echo usage: %~nx0 integer
    goto :EOF
)

set /a dec = %~1, pow = 1073741824

for /L %%I in (1,1,31) do (
    if !dec! geq !pow! (
        set "bin=!bin!1"
        set /a dec -= pow
    ) else (
        if defined bin set "bin=!bin!0"
    )
    set /a pow /= 2
)

if not defined bin set bin=0
echo %bin%

只是因为我觉得它是这样的,但是使用按位操作也是一样的。 这是最有效的方法。 (编辑:或至少是Aacini posted his solution。)

@echo off
setlocal enabledelayedexpansion

if "%~1"=="" (
    echo usage: %~nx0 integer
    goto :EOF
)

for /L %%I in (0,1,30) do (
    set /a "mask = 1 << %%I, bit = ^!^!(%~1 & mask)"
    if !mask! gtr %~1 goto break
    set "bin=!bit!!bin!"
)
:break

if not defined bin set bin=0
echo %bin%

<强>效率:

我运行了一系列测试来确定哪种方法最有效。对于每个方法,我将输出发送到NUL,循环脚本1000次迭代,然后平均运行3次运行。我先用小值5,然后大值2147483646做了这个。结果:

  
      
  • 转到方法,输入=小: 7.37秒
  •   
  • 转到方法,输入=大: 33.77秒
  •   
  • 两种权力方法,输入=小: 8.38秒
  •   
  • 两种权力方法,输入=大: 12.44秒
  •   
  • 按位方法,输入=小: 6.35秒
  •   
  • 按位方法,输入=大: 11.42秒
  •   

这些结果并不令人惊讶,因为for /L通常比goto循环更快,并且按位运算比整数数学运算更快。

答案 1 :(得分:1)

为了完成rojo的回答,我认为this是将十进制数转换为二进制数的最有效方法:

@echo off
setlocal EnableDelayedExpansion

if "%~1"=="" (
    echo usage: %~nx0 integer
    goto :EOF
)

set "decimal=%~1"
set "binary="
for /L %%i in (1,1,32) do (
   set /A "bit=decimal&1, decimal>>=1"
   set "binary=!bit!!binary!"
   if !decimal! equ 0 goto break
)
:break
echo %binary%

请注意,之前的方法正确转换负数

this post,有一个批处理文件可以将非常大的十进制数转换为二进制数。结果存储在Batch变量中,因此二进制数可能最多为8 K位。这意味着可以转换的最大十进制数是2^8192 - 1