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.
{} 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.
== 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.
As you are creating new objects with all those comparisons, all will point to different objects, hence the result will be false .
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.
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With