Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is -1L * -9223372036854775808L == -9223372036854775808L

Tags:

c#

.net

math

binary

f#

I understand this has something to do with the way processors treat overflows, but I fail to see it. Multiplication with different negative numbers gives either zero or -2^63:

In C# Interactive:

> return unchecked (-1L * -9223372036854775808L);
-9223372036854775808
> return unchecked (-2L * -9223372036854775808L);
0
> return unchecked (-3L * -9223372036854775808L);
-9223372036854775808
> return unchecked (-4L * -9223372036854775808L);
0
> return unchecked (-5L * -9223372036854775808L);
-9223372036854775808

In F# Interactive:

> -1L * -9223372036854775808L;;
val it : int64 = -9223372036854775808L
> -2L * -9223372036854775808L;;
val it : int64 = 0L
> -3L * -9223372036854775808L;;
val it : int64 = -9223372036854775808L
> -4L * -9223372036854775808L;;
val it : int64 = 0L

I came to this because it surprised me in F# until I realized that F# by default operates in unchecked contexts. Still, I couldn't readily explain the behavior.

I do understand why 9223372036854775807L + 1L == -9223372036854775808L, I just don't get it for multiplication with a negative number and why it alternates between 0 (binary all zeroes) and -2^63 (binary most significant bit 1, rest zeroes).

Interestingly, this holds with the rule of multiplicative identity, i.e., since -1L * -9223372036854775808L == -9223372036854775808L, it follows that -1L * -1L * -9223372036854775808L == -9223372036854775808L and since -1L * -1L = 1L, it shows that the identity law still holds.

like image 820
Abel Avatar asked Dec 17 '16 23:12

Abel


People also ask

Can you explain why `{} == {}` is false in JavaScript?

{} creates an new object. The comparison operator ==, when used with objects, checks whether two objects are the same one. Since there are two {} in the statement {} == {}, two new objects are created separately, and then they are compared. Since they are not the same object, the result is false.

Why would you use === instead of ==?

== Operator: This operator is used to check the given values are equal or not. If yes, it returns true, otherwise it returns false. === Operator: This operator is used to check the given values and its data type are equal or not. If yes, then it returns true, otherwise it returns false.

Why does [] === [] return false?

As you are creating new objects with all those comparisons, all will point to different objects, hence the result will be false .

What does === means?

The strict equality operator ( === ) checks whether its two operands are equal, returning a Boolean result. Unlike the equality operator, the strict equality operator always considers operands of different types to be different.


1 Answers

The answers you are getting are all correct modulo 2^64: that is, they differ from the mathematically correct answers by a multiple of 2^64, and that's a reasonable definition of a correctly truncated answer.

I'll use ≅ to relate two numbers that are congruent modulo 2^64. Thus

  • -1 * -2^63 = 2^63 ≅ -2^63
  • -2 * -2^63 = 2^64 ≅ 0
  • -3 * -2^63 = 3 * 2^63 = 2^64 + 2^63 ≅ -2^63

and so on. Note that 2^63 and -2^63 are congruent, but it is -2^63 that is representable according to the conventions of twos-complement arithmetic.

like image 51
Mike Spivey Avatar answered Oct 06 '22 14:10

Mike Spivey