ctypesctf

Whats a value of x such that both x + 1 == x and x * 2 == x is true?


Title basically says it all. My friend gave me this as a challenge he solved in some CTF he is doing. I have thought about it for a while and can not figure it out. Also, INFINITY isn't a valid answer. Thanks.


Solution

  • The only way this happens in C is:

    Proof:

    Other than infinity, the statements are mathematically false in real numbers, and therefore this cannot arise from real-number behavior. So it must arise from some non-real-number behavior such as overflow, wrapping, rounding, indeterminate values (which may be different in each use of an object) or uninitialized values. Since * is constrained to have arithmetic operands, we only need to consider arithmetic types. (In C++, one could define a class to make the comparisons true.)

    For signed integers, non-real-number behavior with fully defined values occurs for + and * only when there is overflow, so that is a possibility.

    For unsigned integers, non-real-number behavior with fully defined values occurs for + and * only when there is wrapping. Then, with wrapping modulo M, we would have x+1 = x+kM for some integer k, so 1 = kM, which is not possible for any M used in wrapping.

    For the _Bool type, exhaustive testing of the possible values eliminates them.

    For floating-point numbers, non-real-number behavior with fully defined values occurs for + and * only with rounding, underflow, and overflow and with NaNs. NaNs never compare as equal by IEEE-754 rules, so they cannot satisfy this, except for the fact that the C standard does not require IEEE-754 conformance, so an implementation could choose to make the comparisons true.

    x*2 will not underflow, since it increases the magnitude. x+1 can be made to underflow in a perverse floating-point format with smaller exponent range than precision, but this will not produce x+1 == x. x+1 == x can be satisfied by rounding for sufficiently large x, but then x*2 must produce a value other than x.

    That leaves overflow. If x is the greatest representable finite number (and hence the greatest representable number less than infinity), and the rounding mode is downward (toward −∞) or toward zero, then x+1 will yield x and x*2 will yield x, so the comparisons yield true. Similarly, the greatest negative representable finite number will satisfy the comparisons with rounding upward (toward +∞) or toward zero.