# Who knows what happened in this code? (The difference between 3 and 3.)

I have a problem in my code. This code produces two different results when we use GM = {{Sqrt[3.], 0}, {-Sqrt[3], 3}/2} and GM = {{Sqrt[3], 0}, {-Sqrt[3], 3}/2}, where I just use Sqrt[3] instead of Sqrt[3.] in GM. I do not know what happened to this code. Is there any difference between 3 and 3.?

Block[{R = 6, a = 5, GM, Ks, qs, K1s, K2s, ArrowInd, ArrowInd2,
ind, \[Theta] = 2 Pi/3, Q, con2},
GM = {{Sqrt[3.], 0}, {-Sqrt[3], 3}/2};
con2[x_: {_, _}] := N@Norm@x - R > 0.0001;
{K1s, K2s} =
DeleteCases[
Table[# + l.GM, {l,
Tuples[Range[-#, #] &@Ceiling[2 R/3], 2]}] &[{0, # - 1}/2],
k_ /; con2[k]] & /@ {1, -1};
Ks =
Association[
# -> DeleteCases[
Table[# + l.GM, {l,
Tuples[Range[-#, #] &@Ceiling[2 R/3], 2]}] &[{0, # - 1}/
2],
k_ /; con2[k]] & /@ {1, -1}];
ind = AssociationThread[# -> Range@Length@#] &[Join @@ Ks];
qs = RotationMatrix[# 2 \[Pi]/3].{0, -1} & /@ {0, 1, 2};
ArrowInd =
Join @@ Table[
DeleteCases[ind /@ {#, # + q} & /@ Ks[1], {_, _Missing}], {q, qs}];
ArrowInd2 = (Keys@ind)[[#]] & /@ ArrowInd;
Graphics[{{Arrow[#] & /@ ArrowInd2},
{Gray, Dashed, Circle[{0, 0}, 0.5]}, {Gray, Dashed,
Circle[{0, 0}, R]}, {Red, Point[K1s], Blue, Point[K2s]}},
ImageSize -> 240]]


I'm not sure that an association is the ideal way to handle this, as the keys must be equivalent in order to get a match. This means that if you use machine precision numbers (3.), you could be subject to round-off error which will make the numbers not exactly match any of the keys.

I think this is most easily seen by evaluating the following, once while using 3 and once while using 3.:

ind/@{#, # + qs[[2]]}&/@Ks[1]


The two left columns are the first 10 rows of when we use 3. and the two right columns are from using 3.

$$\begin{array}{cccc} 1 & 45 & 1 & 45 \\ 2 & \text{Missing}[\text{KeyAbsent},\{-1.73205,-4.\}] & 2 & 48 \\ 3 & 49 & 3 & 49 \\ 4 & \text{Missing}[\text{KeyAbsent},\{-3.4641,-1.\}] & 4 & 50 \\ 5 & \text{Missing}[\text{KeyAbsent},\{-4.33013,0.5\}] & 5 & 51 \\ 6 & \text{Missing}[\text{KeyAbsent},\{0.866025,-5.5\}] & 6 & 53 \\ 7 & \text{Missing}[\text{KeyAbsent},\{\text{2.220446049250313\grave{ }*{}^{\wedge}-16},-4.\}] & 7 & 54 \\ 8 & 55 & 8 & 55 \\ 9 & \text{Missing}[\text{KeyAbsent},\{-1.73205,-1.\}] & 9 & 56 \\ 10 & 57 & 10 & 57 \\ \end{array}$$

You can see that there are a lot of mismatches in the case of 3.. Number 7 is particularly notable as you probably aren't intentionally looking through your association for the number 2.20446049250313*^-16. You'll also find that ind[{0, -4}] is missing when you use 3., but returns 54 when you use 3.

Since your code runs pretty fast, it should continue to work so long as you force it to use exact numbers. If your code becomes slow enough that you want to speed it up by using machine precision numbers, then you may need to think of a different way of performing the replacement you're doing. It's very finicky because if the two numbers differ in even the 10th decimal place, the association will tell you that such a key does not exist.