5月30日,有網友在 StackExchange 提了一個問題:
請寫一段程式,使其看似 2 加 2 等於 5。這是一個騙人的測試,但程式不能有任何錯誤,注意記憶體漏洞。輸入操作可選。把 2+2 重定義為 5 就沒那麼有創意了。想都別想哈,試試其他方法唄。
下面整理了部分程式設計師的回帖:
1. Java
1 2 3 4 5 6 7 8 9 10 11 12 13 |
import java.lang.reflect.Field; public class Main { public static void main(String[] args) throws Exception { Class cache = Integer.class.getDeclaredClasses()[0]; Field c = cache.getDeclaredField("cache"); c.setAccessible(true); Integer[] array = (Integer[]) c.get(cache); array[132] = array[133]; System.out.printf("%d",2 + 2); } } |
解釋:
You need to change it even deeper than you can typically access. Note that this is designed for Java 6 with no funky parameters passed in on the JVM that would otherwise change the IntegerCache.
Deep within the Integer class is a Flyweight of Integers. This is an array of Integers from −128 to +127. cache[132]
is the spot where 4 would normally be. Set it to 5.
滑鼠選中上面”空白“區域,可檢視白色字型的解釋。
2. C 語言
1 2 3 4 5 |
int main() { int a = 2 + 2; a++; printf("%d",a); return 0; } |
解釋:
把滾動條往右拖啊!!!
滑鼠選中上面”空白“區域,可檢視白色字型的解釋。
線上測試:http://ideone.com/16PScH#view_edit_box
3. Haskell
1 2 |
λ> let 2+2=5 in 2+2 5 |
4. BBC Basic
1 2 3 4 5 |
MODE 6 VDU 23,52,254,192,252,6,6,198,124,0 PRINT PRINT "2+2=";2+2 PRINT "2+3=";2+3 |
解釋:
This actually prints the number 4, but the VDU 23
redefines the font for ASCII 52 so that it looks like a 5 instead of a 4. Screen mode 6 was selected for aesthetic reasons (characters of a reasonable size.)
滑鼠選中上面的”空白“區域,可檢視白色字型的解釋。
5. Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
public class TwoPlusTwo { public static void main(String... args) { double two = two(); System.out.format("Variable two = %.15f%n", two); double four = Math.ceil(two + two); // round just in case System.out.format("two + two = %.15f%n", four); } // 20 * .1 = 2 private static double two() { double two = 0; for(int i = 0; i < 20; i++) { two += .1; } return two; } } |
輸出結果:
1 2 |
Variable two = 2.000000000000000 two + two = 5.000000000000000 |
解釋:
No, seriously, you always have to round your doubles. 15 isn’t enough digits to show that the two()
method actually produces 2.0000000000000004
(16 is enough, though).
In the raw Hex representations of the numbers, it’s only a 1 bit difference (between 4000000000000001
and 4000000000000000
)… which is enough to make the Math.ceil
method return 5, not 4.
滑鼠選中上面的”空白“區域,可檢視白色字型的解釋。
6. Python
1 2 3 4 |
>>> patch = '\x312\x2D7' >>> import ctypes;ctypes.c_int8.from_address(id(len(patch))+8).value=eval(patch) >>> 2 + 2 5 |
解釋:
Like Java, CPython uses the same memory location for any copy of the first few small integers (0-255 if memory serves). This goes in and directly edits that memory location via ctypes
. patch
is just an obfuscated "12-7"
, a string with len
4, which eval
‘s to 5.
滑鼠選中上面的”空白“區域,可檢視白色字型的解釋。
7. JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
g = function () { H = 3 return H + H } f = function () { Η = 2 return Η + H } // 3 + 3 = 6 alert(g()) // 2 + 2 = 5 alert(f()) |
線上測試:http://jsfiddle.net/qhRJY/
解釋:
Both H (Latin letter capital h) and Η (Greek letter capital eta) are set to the global scope because they were not defined as local to the functions with the var keyword. While they look similar, they are actually 2 different variables with 2 different values. Using Ctrl+F in your browser you will find that Η (eta) shows up significantly less than H (h) on this page.
滑鼠選中上面的”空白“區域,可檢視白色字型的解釋。
8. Bash
1 2 3 4 5 6 7 |
v=2 #v is 2 v+=2 #v is 4 v=$(($v*5)) #v is 20 v=$(($v-16)) #v is 4 v=$(bc<<<"sqrt($v)+2") #v is 4 (sqrt(4) is 2) v=$(bc<<<"$v/4+3") #v is 4 (4/4 = 1) echo '2+2=' $v #So v is 4...? |
輸出:
1 |
2+2= 5 |
解釋:
1 2 3 4 5 6 7 |
v=2 #v is 2 v+=2 #v is 22 v=$(($v*5)) #v is 110 v=$(($v-16)) #v is 94 v=$(bc<<<"sqrt($v)+2") #v is 11 (by default, bc rounds to integers) v=$(bc<<<"$v/4+3") #v is 5 (11/4 is 2 with rounding) echo '2+2=' $v #TADAAAM |
9. PHP
1 |
echo '2 + 2 = ' . (2 + 2 === 4 ? 4 : 2 + 2 === 5 ? 5 : 'dunno'); |
輸出:
1 |
2 + 2 = 5 |
解釋:
1 2 |
This is because in PHP, ternaries are calculated left to right, so it's actually (2 + 2 === 4 ? 4 : 2 + 2 === 5) // 2 + 2 is == 4, and 4 == true, therefore echo 5 ? 5 : 'dunno'; |
10. BrainFuck
1 2 3 4 5 6 7 |
+++++ +++++ + + + + + +++++ +++++ +++ +++++ + + + +++++ + + +++++ +++++. |
線上測試:http://esoteric.sange.fi/brainfuck/impl/interp/i.html
更多其他回覆:http://codegolf.stackexchange.com/questions/28786/write-a-program-that-makes-2-2-5
打賞支援我翻譯更多好文章,謝謝!
打賞譯者
打賞支援我翻譯更多好文章,謝謝!
任選一種支付方式