|
楼主 |
发表于 2009-10-21 20:50
|
显示全部楼层
结贴
函数题 Long值的移位运算 (VBA 的函数题)
做这道题需要了解基础的二进制知识,要了解计算机是如何处理有符号的整数的,参考一楼的二进制演示文件。
有两个名称概念:成员数,序列数,每一个Long值都有两个身份 ,自身值和序列值,这也是此类题目容易让人头晕的地方。
成员数:Long是32位值,有4个字节,成员数= 2^32 或 =256^4 = 4294967296
序列数:自然数中没有0 ,所以跑得最快的人我们叫他第一名,而不会叫他第零名。
从序列上来说0 是第一个Long值,而-1 是最后一个是 第4294967296个。
但数学中是有零的,所以在这里 0 就是第零名,-1 就是4294967295名.
0 和正数的序列数就是自身的值,而负数的序列值则是,成员数+自身值
例如 -1 + 4294967296=4294967295, -2147483648+4294967296= 2147483648,-100000+4294967296=4294867296
位移简单来说就是 序列数*2^移位数,然后把结果转换为Long值。
转换公式为 x= mod(int(序列数*2^移位数),成员数)
结果= if(x<2^31,x,x-2^32)
根据这个思路,我的原始的98字符公式
98字符=INT((A2+2^32*(A2<0))*2^B2)-2^32*INT(((A2+2^32*(A2<0))*2^B2/(2^31)+1)/2)*(INT((A2+2^32*(A2<0))*2^B2)>2^31)
收到 liuzj2s 会员答案 两种方法分别为96 和76字符,他已经可以得满分了。
普通公式 长度=96: =INT(A2*2^B2)-IF(B2<0,-(A2<0)*2^B2,INT(A2*2^(B2-32))+(A2*2^(B2-31)-INT(A2*2^(B2-32))*2>=1))*2^32
普通公式 长度=76: =MOD(INT(((A2<0)*2^32+A2)*2^B2),(-1)^((B2>=0)*MOD(A2*2^B2,2^32)>=2^31)*2^32)
在我把98字符发给liuzj2s 会员交流后,他又给出了更简短 61 和60 字符的答案。
无Mod版
61字符 =INT(A2*2^B2)+((B2<0)*(A2<0)*2^B2-INT(A2*2^(B2-32)+0.5))*2^32
Mod版
60字符 =INT(MOD(A2,2^32)*2^B2)-INT(MOD(A2,2^32)*2^(B2-32)+0.5)*2^32
同时我也发现,我的98字符的公式最后30个字符纯粹多余 *(INT((A2+2^32*(A2<0))*2^B2)>2^31) ,去掉这一部分后变为68字符。
68字符 =INT((A2+2^32*(A2<0))*2^B2)-2^32*INT((A2+2^32*(A2<0))*2^(B2-32)+0.5)
再简化到66字符
66字符 =INT((A2+2^32*(A2<0))*2^B2)-2^32*INT(A2*2^(B2-32)+2^B2*(A2<0)+0.5)
所有的 int(xxx+0.5) 可用 round(xxx,)代替,最终我的答案成为65字符
65字符 =INT((A2+2^32*(A2<0))*2^B2)-2^32*ROUND(A2*2^(B2-32)+2^B2*(A2<0),)
liuzj2s 会员的最终答案可缩短至60 和59
60字符 =INT(A2*2^B2)+((B2<0)*(A2<0)*2^B2-ROUND(A2*2^(B2-32),))*2^32
59字符 =INT(MOD(A2,2^32)*2^B2)-ROUND(MOD(A2,2^32)*2^(B2-32),)*2^32
到最后一刻,方版主的答案让我吃惊不小,关键问题想到了就容易了,其中一些技巧太值得学习。
64字符 =INT(A2*2^B2-INT(A2*2^(B2-32)+0.5)*2^32+(A2<0)*(B2<0)*2^(32+B2))
65字符 =INT((A2+(A2<0)*2^32)*2^B2-ROUND(A2*2^(B2-32)+(A2<0)*2^B2,)*2^32)
47字符 =INT(MOD((A2+(A2<0)*2^32)*2^B2+2^31,2^32)-2^31)
虽然字符长短与运行效率没有必然联系,但函数公式的运行效率并不好测试。
如果函数竞赛追求效率为上的话,很多时候两个甚至多个单元格,运行效率比一个单元格要快。
这就很难确定一个标准,作为竞赛来说最直观的就是公式的长短,这也是大多数函数题所采用的评分标准。
在更好的评分标准出现之前,公式的长度限制将是主要的评分标准。
我个人的看法是通过函数竞赛,可以加深对函数的了解,扩充知识面,活跃思维。
这就像邓爷爷打桥牌,不为输赢,为的是要保持一个思路清晰、敏捷的头脑。
目前的最短答案60和47字符未必就是最短的,此题虽然已结题,但如有兴趣,在此基础上更近一步,依然会获得加分鼓励。 |
评分
-
1
查看全部评分
-
|