Can anyone explain why the value of a android resource id (R.id.navigation_news) before and after passing to a function is different?
Before pass to function
fun showTabFragment() {
navigateWithStartDest(R.id.navigation_news) // R.id.navigation_news == -1000386
}
After
fun navigateWithStartDest(resId:Int){
//resId == 2131362119
//resId != R.id.navigation_news - true
...
}
Probably you get integer overflow. The reason is your integer is too big.
In computer programming, an integer overflow occurs when an arithmetic operation attempts to create a numeric value that is outside of the range that can be represented with a given number of digits – either larger than the maximum or lower than the minimum representable value.
See the link:
https://en.wikipedia.org/wiki/Integer_overflow
The solution is not operate on R.id values, but only pass them as resources.
It could occur because of Java memory model. In kotlin language all primitives turned into objects. So in your function you receive not exact value but reference for it.
Related
(Moved from https://softwareengineering.stackexchange.com/questions/406813/how-to-implement-fnv-1a-in-sqlite)
I'm trying to modify a SQLite query (in Android) to return its results in pseudorandom order. As in this question, the order needs to be stable over repeated queries (e.g. due to paging, screen rotation, etc.), so I can't just use ORDER BY RANDOM(). Instead I want to use a hash function that depends on a couple of input values that provide stability and sufficient uniqueness. (One of these values is a unique ID column of the table, which is a set of integers fairly close together; the other value is more like an session ID, also an integer, that remains invariant within this query.)
According to this well-researched answer, FNV-1 and FNV-1a are simple hash functions with few collisions and good distribution. But as simple as they are, FNV-1 and FNV-1a both involve XOR operations, as well as looping over the bytes of input.
Looping within each row of a query is pretty awkward. One could fake it by unrolling the loop, especially if only a few bytes are involved. I could make do with two bytes, combining LSBs from the two input values (val1 & 255 and val2 & 255).
XOR isn't supported directly in SQLite. I understand A ^ B can be implemented as (A | B) - (A & B). But the repetition of values, combined with the unrolling of the loop, starts to get unwieldy. Could I just use + (ignoring overflow) instead of XOR? I don't need very high quality randomness. The order just needs to look random to a casual observer over small-integer scales.
So I'm wondering if anyone has already implemented such a thing. Given how widely used this hash function is, it seems like there would likely already be an implementation for this situation.
Here's my attempt at implementing FNV-1a:
SELECT ..... ORDER BY (((fnvbasis + val1 & 255) * fnvprime) + val2 & 255) * fnvprime % range;
I'm ignoring the fact that in FNV, the XOR operation (which I've replaced with +) is only supposed to affect the lowest 8 bits of the hash value. I'm also ignoring any overflow (which I hope just means the upper bits, which I don't care about, are lost).
For fnvbasis I'll use 16777619, and for fnvprime I'll use 2166136261. These are the specified values for 32 bit input, since I don't see a specified value for 16 bit input. For range I'll use a prime number that's greater than the expected number of rows returned by this query.
So is this a reasonable way to approximate FNV-1a in a SQLite query? Is there a better, existing implementation? I.e. will it actually produce an ordering that looks pretty random to a casual user, despite my mutilating the operations of the real FNV-1a?
Inspired by comments from rwong and GrandmasterB on the previous attempt at this question before I moved it, I decided I could precompute the first iteration of FNV-1a's loop, i.e. the hash based on the unique ID column of the table. The precomputed column, fnv1a_step1, is set to
(fnvbasis ^ (ID & 0xFF)) * fnvprime
Because this value is precomputed on each row of the table separately, it can be supplied by the app and doesn't need to be expressed in SQLite; hence the use of ^ (XOR) above. Also, if ID is a string, we can compute an 8-bit hash value from it in Java or Kotlin as well. But we could even use
(fnvbasis + (RANDOM() & 0xFF)) * fnvprime
(back to using + if doing this in SQLite) because the value is only computed once, and therefore is stable even when computed from RANDOM().
The second iteration of the FNV-1a loop can be computed pretty simply in the ORDER BY clause of the query, using the current session ID, so it produces a different-but-stable ordering for each session:
ORDER BY (fnv1a_step1 + sessionId & 0xFF) * fnvprime % range;
I've implemented this in my app, and it seems to work, to my requirements. The order is stable within a session, but is different in each session.
The default String compareTo() function compares lexicographically i.e character by character.
E.g. String "3222368" is lesser than "9876135" because 3 < 9.
But i want to compare the whole value based on how swift does it. The sections of importance -
Comparing Strings Using Operators
Comparing strings using the equal-to
operator (==) or a relational operator (like < and >=) is always
performed using the Unicode canonical representation, so that
different representations of a string compare as being equal.
AND
static func <=(String, String)
Returns a Boolean value indicating whether the value of the first
argument is less than or equal to that of the second argument
How can i do this in Java ?
I tried looking up java.text.Collator
and tried this -
Collator myDefaultCollator = Collator.getInstance();
return myDefaultCollator.compare(string1, string2);
and it's not working.
Could you help me out ?
UPDATE:
I'm looking to sort the strings using the compareTo() method.
I'm actually using Math.sin() in my android app to calculate a sinus of a given angle (using Math.toRadians(angle_in_degrees)). For exemple when I want to get the Math.cos(90) which is 0, the result is 6.123233... E-17. Thanks you.
For floating point numbers, the system can often only approximate their values. For instance, the system would return something like 0.333333 for the expression (1.0 / 3). The number of 3s after the decimal point will be different depending on whether you're a floats or doubles, but it will still be limited to some finite length.
If you're just displaying the value, then you can limit the number of digits using something like String.format("%0.2f", value) or by rounding it using one of the rounding functions such as Math.round().
The tricky part comes when you need to compare the value to something. You can't just use if (value == some_constant) or even if (value == some_variable). At minimum, you usually have to use something like if (Math.abs(value - some_constant) < 0.001). The actual value of the '0.001' depends on the needs of your particular application and is customarily defined as a named constant.
For more complicated needs, you can implement the algorithm in the Floating-Point Guide.
You're getting back an approximation from Math.cos(Math.toRadians(90)) which is
6.123233... E-17 == 0.00000000000000006123233... which is basically 0
The following link should help clear things up as far as the precision of doubles/floats in programming.
http://www.java67.com/2015/09/float-and-double-value-comparison-in-java-use-relational.html
I see that AbstractWindowedCursor has methods to check the type of a column. This is a great convenience! But when I look at the CursorWindow class, I see that the documentation for isBlob() says:
Checks if a field contains either a blob or is null.
So, does this mean that if I run this check on, say, a String column that contains a NULL value, will it return true? If so, this means I can't rely on that method as a guaranteed type check.
Checks if a field contains either a blob or is null.
So, does this mean that if I run this check on, say, a String column that contains a NULL value, will it return true?
I haven't tried it myself but I suspect the answer is 'yes' (either that or there's a typo in the docs).
However, if you run isNull() first and that returns 'true' then you know that it isn't going to be possible to tell what the 'column' type is anyway (the isXxxx methods check the type of data the 'field' contains not the 'column' type).
But if you run isNull() first and it returns 'false' then run isBlob(), if it returns true the field contains a blob.
I have a number (123456) converted to a hash key and stored in SharedPrefs using:
String correctMd5 = passwdfile.getString(PhoneFinder.PASSWORD_PREF_KEY, null);
I then retreive the number from a string:
String[] tokens = msg.getMessageBody().split(":");
String md5hash = PhoneFinder.getMd5Hash(tokens[1]);
and compare the two:
if (correctMd5 == md5hash) {
Toast.makeText(context, "Hash OK: " + md5hash, Toast.LENGTH_SHORT).show();
}
However, this check does not complete succesfully.
If I convert to strings and display them, the hashes are the same, however if I convert to bytes the 4 right most bytes are different. I assume some special character is hidden in there somewhere, how do I check and kill it?
You should probably use correctMd5.equals(md5hash) instead of the correctMd5 == md5hash.
Is it solving the problem ?
The problem appears to be:
correctMd5 == md5hash
Because a String is an Object in Java (Android) this will compare the Object, not its String value. For instance, if you have two different variables they might be in 2 different memory locations, or they might be references to the same memory location.
On the other hand, if you want to find out if the VALUES stored by the memory location are equal, you should use
correctMd5.equals(md5hash)
In your conditional, you could have two strings "1000" and "1000" but stored at different memory locations. In my conditional, it will still be true regardless of memory location, if the String values are equal.
If == is true, .equals() should be true (in most cases, if not all). But if .equals() is true, there is no guarantee that == is true.