The main reason is numerical accuracy. See the SO post for a discussion related to R. @ Dirk-eddelbuettel's links include both R and one of the most relevant articles covering numerical accuracy in general. This post contains a more detailed general answer to SO related to the informatics behind this issue.
To show that the main reason is numerical accuracy, consider the sequence you created. First, the default print out of sequence.
print(seq(0,1, by = 0.01) * 100 + 1) [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 [20] 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 [39] 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 [58] 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 [77] 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 [96] 96 97 98 99 100 101
Everything looks good. Now print your sequence by telling R to show 16 digits.
print(seq(0,1, by = 0.01) * 100 + 1, digits=16) [1] 1.000000000000000 2.000000000000000 3.000000000000000 [4] 4.000000000000000 5.000000000000000 6.000000000000000 ... [25] 25.000000000000000 26.000000000000000 27.000000000000000 [28] 28.000000000000000 29.000000000000004 29.999999999999996 [31] 31.000000000000000 32.000000000000000 33.000000000000000 [34] 34.000000000000000 35.000000000000000 36.000000000000000 [37] 37.000000000000000 38.000000000000000 39.000000000000000 [40] 40.000000000000000 41.000000000000000 42.000000000000000 [43] 43.000000000000000 44.000000000000000 45.000000000000000 [46] 46.000000000000000 47.000000000000000 48.000000000000000 [49] 49.000000000000000 50.000000000000000 51.000000000000000 [52] 52.000000000000000 53.000000000000000 54.000000000000000 [55] 55.000000000000000 56.000000000000007 57.000000000000007 [58] 58.000000000000007 58.999999999999993 60.000000000000000 ... [100] 100.000000000000000 101.000000000000000
You see that “30” stores the value 29.999999999999996 and “59” stores the value 58.999999999999993. Now, if we pass this sequence as an integer, we get the following output.
print(as.integer(seq(0,1, by = 0.01) * 100 + 1)) [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 [20] 20 21 22 23 24 25 26 27 28 29 29 31 32 33 34 35 36 37 38 [39] 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 [58] 58 58 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 [77] 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 [96] 96 97 98 99 100 101
This coercive function was translated 2999999999999999996 to 29 and 58.999999999999993-58, essentially performing truncation. So in your code the 29th and 58th elements are referenced twice, while the 30th and 59th elements are not referenced at all.
In this situation, the output is identical to using the floor function.
identical(trunc(seq(0,1, by = 0.01) * 100 + 1), floor(seq(0,1, by = 0.01) * 100 + 1)) [1] TRUE
One solution to your specific problem is to use round before passing the sequence to an integer.
identical(1:101, as.integer(round(seq(0,1, by = 0.01) * 100 + 1))) [1] TRUE