Related
As of Java 1.5, you can pretty much interchange Integer with int in many situations.
However, I found a potential defect in my code that surprised me a bit.
The following code:
Integer cdiCt = ...;
Integer cdsCt = ...;
...
if (cdiCt != null && cdsCt != null && cdiCt != cdsCt)
mismatch = true;
appeared to be incorrectly setting mismatch when the values were equal, although I can't determine under what circumstances. I set a breakpoint in Eclipse and saw that the Integer values were both 137, and I inspected the boolean expression and it said it was false, but when I stepped over it, it was setting mismatch to true.
Changing the conditional to:
if (cdiCt != null && cdsCt != null && !cdiCt.equals(cdsCt))
fixed the problem.
Can anyone shed some light on why this happened? So far, I have only seen the behavior on my localhost on my own PC. In this particular case, the code successfully made it past about 20 comparisons, but failed on 2. The problem was consistently reproducible.
If it is a prevalent problem, it should be causing errors on our other environments (dev and test), but so far, no one has reported the problem after hundreds of tests executing this code snippet.
Is it still not legitimate to use == to compare two Integer values?
In addition to all the fine answers below, the following stackoverflow link has quite a bit of additional information. It actually would have answered my original question, but because I didn't mention autoboxing in my question, it didn't show up in the selected suggestions:
Why can't the compiler/JVM just make autoboxing “just work”?
The JVM is caching Integer values. Hence the comparison with == only works for numbers between -128 and 127.
Refer: #Immutable_Objects_.2F_Wrapper_Class_Caching
You can't compare two Integer with a simple == they're objects so most of the time references won't be the same.
There is a trick, with Integer between -128 and 127, references will be the same as autoboxing uses Integer.valueOf() which caches small integers.
If the value p being boxed is true, false, a byte, a char in the range \u0000 to \u007f, or an int or short number between -128 and 127, then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2.
Resources :
JLS - Boxing
On the same topic :
autoboxing vs manual boxing java
"==" always compare the memory location or object references of the values. equals method always compare the values. But equals also indirectly uses the "==" operator to compare the values.
Integer uses Integer cache to store the values from -128 to +127. If == operator is used to check for any values between -128 to 127 then it returns true. for other than these values it returns false .
Refer the link for some additional info
Integer refers to the reference, that is, when comparing references you're comparing if they point to the same object, not value. Hence, the issue you're seeing. The reason it works so well with plain int types is that it unboxes the value contained by the Integer.
May I add that if you're doing what you're doing, why have the if statement to begin with?
mismatch = ( cdiCt != null && cdsCt != null && !cdiCt.equals( cdsCt ) );
The issue is that your two Integer objects are just that, objects. They do not match because you are comparing your two object references, not the values within. Obviously .equals is overridden to provide a value comparison as opposed to an object reference comparison.
Besides these given great answers, What I have learned is that:
NEVER compare objects with == unless you intend to be comparing them
by their references.
As well for correctness of using == you can just unbox one of compared Integer values before doing == comparison, like:
if ( firstInteger.intValue() == secondInteger ) {..
The second will be auto unboxed (of course you have to check for nulls first).
pseudocode:
// deprecated x!=y && hash(x) == hash(y) // how to make this true?
x!=y && hash(x) == hash(y) && (z!=x && z!=y) && (hash(x) != hash(z) && (hash(y) != hash(z)) // how to make this true?
x and y can be any readable value
Whatever the language, the pseudocode is just help to understand what I mean.
I just wonder how to implement such hash function.
PS: For math, i am an idiot. I can not imagine if there is an algorithm that can do this.
UPDATE 1:
The pseudocode has bug, so I updated the code(actually still has bug, never mind, I will explain).
My original requirement is to make a hash function that can return same value for different parameter, and the parameter value should contains some rule. It means, only the parameter value in same category would gets same hash code, others are not.
e.g.
The following expressions are clearly(you can treat '0' as placeholder):
hash("1.1") == hash("1.0") == hash("0.1")
hash("2.2") == hash("2.0") == hash("0.2")
and
hash("2.2") != hash("2.1") != hash("1.2")
I think this question can do such description:
There are two or more different values contains implied same attribute.
Only these values have such same attribute in the world.
The attribute can obtain through some way(maybe a function), hash() will call it inside.
hash() one of the values, you can retrive the attribute, then you can get the unique hashCode.
It's looks like hash collision, but we exactly know what they are. Also looks like many-to-one model.
How to design collision rules? The values could be any character or numeric. And how to implement the designs?
PPS: This is a question full of bugs, maybe the updated parts cannot explain the the problem either. Or maybe this is a false proposition. I want abstract my issue as a general model, but it makes my mind overflowed. If necessary I will post my actual issue that I am facing.
Any constant hash trivially satisfies your condition:
hash(v) = 42
A less constant answer than yuri kilocheck's would be to use the mod operator:
hash(v) = v % 10;
Then you'll have:
hash(1) = 1
hash(2) = 2
hash(3) = 3
...
hash(11) = 1
hash(12) = 2
Why on earth does comparing a float value of 1.0, to an integer value of 1, return true?
puts '1.0'.to_i
puts '1.0'.to_i == 1.0 #so 1 == 1.0 is true?
puts 1.0 == 1 #wtf?
Does Ruby only read the first part of the floatin point value and then short circuit? Wuld someone be able to explain with a link to some documentation please? I have flipped through the API but I don't even know what to look for in this case...
== compares the value, the value of 1.0 is equal to 1 in math, so it's not much surprising. To compare value as well as type, you can use eql?:
1.0 == 1
#=> true
1.0.eql? 1
#=> false
In Ruby, == is a method. That means to understand it you need to look at the specific class calling it.
1 == 1.0
The caller is 1, a Fixnum. So you need to look at Fixnum#==.
1.0 == 1
The caller is 1.0, a Float. So you need to look at Float#==.
A surprising result of this is that == is not necessarily symmetric: a == b and b == a could call completely different methods and return completely different results. In this case though, both == methods end up calling the C function rb_integer_float_eq which converts both operands to the same data type before comparing them.
Actually there already is a nice answer "What's the difference between equal?, eql?, ===, and ==?" about equality in Ruby, with references and stuff. There is a surprising amount of ways to compare for equality in Ruby, each with its own purpose.
Since mathematical meaning is not enough for you, you can compare differently. Like, say, eql? that is heavily used in Hashes to determine if two keys are the same. And it turns out that 1.0 and 1 are different keys! his is what I get in IRB of Ruby 2.1.2:
> 1.0.eql?(1.0)
=> true
> 1.eql?(1)
=> true
> 1.eql?(1.0)
=> false
Ruby is coercing the operands of == (as needed) to the same type, then performing a comparison of their numeric values. This is normally what you want for numeric comparisons.
Most languages will automatically increase the precision of a variable's type in order to perform operations on them such as compare, add, multiply, etc. They "usually" do not decrease the precision, nor unnecessarily increase it. E.g. 1/2 = 0, but 1.0/2.0 = 0.5.
I have an Ada enum with 2 values type Polarity is (Normal, Reversed), and I would like to convert them to 0, 1 (or True, False--as Boolean seems to implicitly play nice as binary) respectively, so I can store their values as specific bits in a byte. How can I accomplish this?
An easy way is a lookup table:
Bool_Polarity : constant Array(Polarity) of Boolean
:= (Normal=>False, Reversed => True);
then use it as
B Boolean := Bool_Polarity(P);
Of course there is nothing wrong with using the 'Pos attribute, but the LUT makes the mapping readable and very obvious.
As it is constant, you'd like to hope it optimises away during the constant folding stage, and it seems to: I have used similar tricks compiling for AVR with very acceptable executable sizes (down to 0.6k to independently drive 2 stepper motors)
3.5.5 Operations of Discrete Types include the function S'Pos(Arg : S'Base), which "returns the position number of the value of Arg, as a value of type universal integer." Hence,
Polarity'Pos(Normal) = 0
Polarity'Pos(Reversed) = 1
You can change the numbering using 13.4 Enumeration Representation Clauses.
...and, of course:
Boolean'Val(Polarity'Pos(Normal)) = False
Boolean'Val(Polarity'Pos(Reversed)) = True
I think what you are looking for is a record type with a representation clause:
procedure Main is
type Byte_T is mod 2**8-1;
for Byte_T'Size use 8;
type Filler7_T is mod 2**7-1;
for Filler7_T'Size use 7;
type Polarity_T is (Normal,Reversed);
for Polarity_T use (Normal => 0, Reversed => 1);
for Polarity_T'Size use 1;
type Byte_As_Record_T is record
Filler : Filler7_T;
Polarity : Polarity_T;
end record;
for Byte_As_Record_T use record
Filler at 0 range 0 .. 6;
Polarity at 0 range 7 .. 7;
end record;
for Byte_As_Record_T'Size use 8;
function Convert is new Ada.Unchecked_Conversion
(Source => Byte_As_Record_T,
Target => Byte_T);
function Convert is new Ada.Unchecked_Conversion
(Source => Byte_T,
Target => Byte_As_Record_T);
begin
-- TBC
null;
end Main;
As Byte_As_Record_T & Byte_T are the same size, you can use unchecked conversion to convert between the types safely.
The representation clause for Byte_As_Record_T allows you to specify which bits/bytes to place your polarity_t in. (i chose the 8th bit)
My definition of Byte_T might not be what you want, but as long as it is 8 bits long the principle should still be workable. From Byte_T you can also safely upcast to Integer or Natural or Positive. You can also use the same technique to go directly to/from a 32 bit Integer to/from a 32 bit record type.
Two points here:
1) Enumerations are already stored as binary. Everything is. In particular, your enumeration, as defined above, will be stored as a 0 for Normal and a 1 for Reversed, unless you go out of your way to tell the compiler to use other values.
If you want to get that value out of the enumeration as an Integer rather than an enumeration value, you have two options. The 'pos() attribute will return a 0-based number for that enumeration's position in the enumeration, and Unchecked_Conversion will return the actual value the computer stores for it. (There is no difference in the value, unless an enumeration representation clause was used).
2) Enumerations are nice, but don't reinvent Boolean. If your enumeration can only ever have two values, you don't gain anything useful by making a custom enumeration, and you lose a lot of useful properties that Boolean has. Booleans can be directly selected off of in loops and if checks. Booleans have and, or, xor, etc. defined for them. Booleans can be put into packed arrays, and then those same operators are defined bitwise across the whole array.
A particular pet peeve of mine is when people end up defining themselves a custom boolean with the logic reversed (so its true condition is 0). If you do this, the ghost of Ada Lovelace will come back from the grave and force you to listen to an exhaustive explanation of how to calculate Bernoulli sequences with a Difference Engine. Don't let this happen to you!
So if it would never make sense to have a third enumeration value, you just name objects something appropriate describing the True condition (eg: Reversed_Polarity : Boolean;), and go on your merry way.
It seems all I needed to do was pragma Pack([type name]); (in which 'type name' is the type composed of Polarity) to compress the value down to a single bit.
I was coding here the other day, writing a couple of if statements with integers that are always either 0 or 1 (practically acting as bools). I asked myself:
When testing for positive result, which is better; testing for int == 1 or int != 0?
For example, given an int n, if I want to test if it's true, should I use n == 1 or n != 0?
Is there any difference at all in regards to speed, processing power, etc?
Please ignore the fact that the int may being more/less than 1/0, it is irrelevant and does not occur.
Human's brain better process statements that don't contain negations, which makes "int == 1" better way.
It really depends. If you're using a language that supports booleans, you should use the boolean, not an integer, ie:
if (value == false)
or
if (value == true)
That being said, with real boolean types, it's perfectly valid (and typically nicer) to just write:
if (!value)
or
if (value)
There is really very little reason in most modern languages to ever use an integer for a boolean operation.
That being said, if you're using a language which does not support booleans directly, the best option here really depends on how you're defining true and false. Often, false is 0, and true is anything other than 0. In that situation, using if (i == 0) (for false check) and if (i != 0) for true checking.
If you're guaranteed that 0 and 1 are the only two values, I'd probably use if (i == 1) since a negation is more complex, and more likely to lead to maintenance bugs.
If you're working with values that can only be 1 or 0, then I suggest you use boolean values to begin with and then just do if (bool) or if (!bool).
In language where int that are not 0 represents the boolean value 'true', and 0 'false', like C, I will tend to use if (int != 0) because it represents the same meaning as if (int) whereas int == 1 represents more the integer value being equal to 1 rather than the boolean true. It may be just me though. In languages that support the boolean type, always use it rather than ints.
A Daft question really. If you're testing for 1, test for 1, if you're testing for zero, test for zero.
The addition of an else statement can make the choice can seem arbitrary. I'd choose which makes the most sense, or has more contextual significance, default or 'natural' behaviour suggested by expected frequency of occurrence for example.
This choice between int == 0 and int != 1 may very well boil down to subjective evaluations which probably aren't worth worrying about.
Two points:
1) As noted above, being more explicit is a win. If you add something to an empty list you not only want its size to be not zero, but you also want it to be explicitly 1.
2) You may want to do
(1 == int)
That way if you forget an = you'll end up with a compile error rather than a debugging session.
To be honest if the value of int is just 1 or 0 you could even say:
if (int)
and that would be the same as saying
if (int != 0)
but you probably would want to use
if (int == 1)
because not zero would potentially let the answer be something other than 1 even though you said not to worry about it.
If only two values are possible, then I would use the first:
if(int == 1)
because it is more explicit. If there were no constraint on the values, I would think otherwise.
IF INT IS 1
NEXT SENTENCE
ELSE MOVE "INT IS NOT ONE" TO MESSAGE.
As others have said, using == is frequently easier to read than using !=.
That said, most processors have a specific compare-to-zero operation. It depends on the specific compiler, processor, et cetera, but there may be an almost immeasurably small speed benefit to using != 0 over == 1 as a result.
Most languages will let you use if (int) and if (!int), though, which is both more readable and get you that minuscule speed bonus.
I'm paranoid. If a value is either 0 or 1 then it might be 2. May be not today, may be not tomorrow, but some maintenance programmer is going to do something weird in a subclass. Sometimes I make mistakes myself [shh, don't tell my employer]. So, make the code say tell me that the value is either 0 or 1, otherwise it cries to mummy.
if (i == 0) {
... 0 stuff ...
} else if (i == 1) {
... 1 stuff ...
} else {
throw new Error();
}
(You might prefer switch - I find its syntax in curly brace language too heavy.)
When using integers as booleans, I prefer to interpret them as follows: false = 0, true = non-zero.
I would write the condition statements as int == 0 and int != 0.
I would say it depends on the semantics, if you condition means
while ( ! abort ) negation is ok.
if ( quit ) break; would be also ok.
if( is_numeric( $int ) ) { its a number }
elseif( !$int ) { $int is not set or false }
else { its set but its not a number }
end of discussion :P
I agree with what most people have said in this post. It's much more efficient to use boolean values if you have one of two distinct possibilities. It also makes the code a lot easier to read and interpret.
if(bool) { ... }
I was from the c world. At first I don't understand much about objective-c. After some while, I prefer something like:
if (int == YES)
or
if (int == NO)
in c, i.e.:
if (int == true)
if (int == false)
these days, I use varchar instead of integer as table keys too, e.g.
name marital_status
------ --------------
john single
joe married
is a lot better than:
name marital_status
------ --------------
john S
joe M
or
name marital_status
------ --------------
john 1
joe 2
(Assuming your ints can only be 1 or 0) The two statements are logically equivalent. I'd recommend using the == syntax though because I think it's clearer to most people when you don't introduce unnecessary negations.