返回列表 发帖
嗯,笔误,呵呵 

TOP

本帖最后由 applba 于 2011-4-28 23:45 编辑

给出个求极大值的捷径:
通过二进制移位来给2开方,一直开到溢出,溢出后其结果是负的,以此负值判断结束条件。
@echo off &setlocal enabledelayedexpansion
for /l %%i in  (1,1,256) do (
    set /a "_tmp=1<<%%i"
    if !_tmp! leq 0 (
        set /a "t2=%%i-1"
        set  /a "max=((1<<!t2!)-1)+(1<<!t2!)"
        goto 2out
    )
)
:2out
echo 2!t2!次方最接近极大值!max!
pause>nulCOPY
我用for是和256是因为我还没有看到支持256bit数据类型的编程语言和操作系统……
当然你喜欢用goto也没什么问题的……

TOP

本帖最后由 applba 于 2011-4-27 13:24 编辑

既然上面求了极大值,现在就不存在溢出问题了:
@echo off &setlocal enabledelayedexpansion
:input
cls
set /p _n=请输入正整数:
set /a  n=!_n!&&if  !n! lss 2 goto input
set  /a "varup=1,vardn=2147483647"
for /l %%i in (1,1,30) do (
        set /a "varup=!varup!*!n!,vardn=!vardn!/!n!"
        set /a "var=!vardn!/!varup!"
        if !var! lss !n! (
                if !var! equ 0 (set /a "cnt=2*%%i-1" && goto out)
                set /a "cnt=2*%%i" && goto out
        )
)
:out
echo !n!!cnt!次方接近最大值!
PAUSE&goto inputCOPY
思路也很简单,正反一起用,往中间碰撞……

TOP

给出个求极大值的捷径:(此方法通用于所有二进制计算机)
通过二进制逻辑移位来给2开方,一直开到溢出,溢出后其结果是负的,以此负值判断结束条件。
@echo off &setlocal enabledelayedexpansion
for /l %%i in ...
applba 发表于 2011-4-27 09:41


求极值的方法很多
比如11楼的方法
如果非要用二进制移位,也可以这样
@echo off &setlocal enabledelayedexpansion
for /l %%i in  (1,1,256) do (
    set /a "_tmp=1<<%%i"
    if !_tmp! leq 0 (
        set /a "t2=%%i-1"
        set  /a "max=_tmp-1"
        goto 2out
    )
)
:2out
echo 2的!t2!次方最接近极大值!max!
pause>nul
天的白色影子

TOP

思路也很简单,正反一起用,往中间碰撞……
applba 发表于 2011-4-27 10:02

正反同时碰撞的思路不错
可以看考虑修改一下以支持负整数(除-2以外与正整数相同)和超大数(结果是0)
天的白色影子

TOP

34# qzwqzw


汗,我把这个极值翻转居然给忘了………………

就是不知道这个通用性如何?

TOP

本帖最后由 applba 于 2011-4-27 13:33 编辑

35# qzwqzw


请教  第八行和第九行合并(用逗号)表达式后,结果会异常,但是程序运行都正常的……

超级大数?在cmd.exe是输不进去的,你赋值的时候提示无效……

关于负数很好弄吧,只看正值就行了, for i=(0,2,30)就行了?

TOP


请教  第八行和第九行合并(用逗号)表达式后,结果会异常,但是程序运行都正常的……

这个,你去掉set /a 后面的!试试
也就是说不使用变量延迟扩展

超级大数?在cmd.exe是输不进去的,你赋值的时候提示无效……

你是用什么处理输入数的
可以看一下我14楼的代码
它是支持超大数的

关于负数很好弄吧,只看正值就行了, fo ...

没理解你想说的意思
最好能有代码实现让我看看
天的白色影子

TOP

合并算式的时候要注意预处理,要不然变量并不一定会按照我们所想的顺序去拓展
        set /a "varup=!varup!*!n!,vardn=!vardn!/!n!","var=vardn/varup"

TOP

忽然想到这正是判断n是否为2的倍数的最快办法:set /a "test=1/(1073741824*n)"||echo %n%为2的倍数
zm900612 发表于 2011-3-14 16:41

搞错了吧,应该是判断n是否为4的倍数才对,不信试试下面的代码:
@echo off
set n=2
:loop
set /a "test=1/(1073741824*n)" 2>nul||echo %n%
set /a n+=2
if %n% lss 100 goto:loop
pauseCOPY

TOP

嗯,忘了溢出后的-2147483648是合法的,不过也好办,改成:
set /a "test=1/(1073741824*2*n)"||echo %n%

TOP

看了半天,后面全部离题了。。。

所谓的“正算反算”应该是 nx=n*n 之后,再求 n <> nx/n  的循环次数。

一个数乘了以后如果溢出,那么反过来这个溢出数除了之后肯定不等于原来的数了。

TOP

代码放上
@echo off
set /p in=请输入正整数:
set /a inx=in
for /l %%i in (1,1,100) do (
2>nul  set /a ix=inx*in,"1/!(ix / inx - in)",inx=ix ||call :end %%i
)
:end
echo %in%%1次方接近于CMD最大值,值为%inx%。
pause>nul&exitCOPY
1

评分人数

TOP

判断是否2的倍数,只要知道最后一个字节是0是1就可以了。

哪怕最直接的 % 2 ,求余数都比你那个复杂的计算要快。

TOP

44# caruko


确实,当时思维绕弯了,21楼也指出了这个问题

TOP

返回列表