So, why we have this initializer for an Array
let a = Array(repeating: _, count: Int) and not let a = Array(repeating: _, count: UInt64)
Index in an array can not be negative. And iOS 9 does not allow me to make well capacity array for storing all seconds since 1970 year.
cukr
3
There are two ways of manipulating indices:
- using index apis, like
firstIndex, or index(after:)
If you use them, you don't care if index is signed or unsigned, because you don't ever touch it as a number
- using arithmetics, like
arr[3-foo+bar]
if you manipulating indices like that you have to be careful anyway, because -1 is as wrong as size+1 or even 3 when you meant 2.
If you manipulate indices with arithmetics though, Int has an advantage over UInt because you don't have to convert your numbers back and forth between signed and unsigned, and you can temporarily go into negatives when computing the final index
1 Like
I understand about interoperability, but next simple and useful code does not work on iOS9
let searchIndex = Int(Date().timeIntervalSince1970 * 10)
let z = [1, 2, 3][searchIndex]
Because of overflowing Int value
Lantua
5
You're accessing element beyond the 4294967296th. You need at least 16GB to store that many data on 32-bit machine, doubling that for 64-bit. That's a lot of space. I think you'd be better off rolling your own storage.
Also, since Date().timeIntervalSince1970 * 10 ~ 15840M, you'd need at least 59GB on 32-bit machine.
1 Like
It is not actually storage, the [1, 2, 3] may be GenericStruct which works with Array.Index type. I mean iOS9 is off-board already for modern code.
Lantua
7
What're you trying to do? Collection.Index is only appropriate to use with that Collection. If you have your own GenericStruct, then you should decide your own appropriate Index.
Also your original question is about Array(repeating: _, count: Int) which creates Array, not GenericStruct.
I have a collection with 300 capacity. And I'm trying to get all seconds from 1970 and divide it to my capacity and get a reminder for getting an index of an element. A generics example from my previous post is not quite good for now.
Lantua
9
Ok, from the look of it, you’re trying to cram all those entries into an array of 300 elements.
There are 2 ways you can do it.
- Wrap the array in your custom implementation of
TimestampEntries, which of course, would have UInt64 as an Index, or
- Use
UInt64 in your computation, and convert them to Int when accessing array.
It seems you’re trying to do 2. the reason it doesn’t work is that, you have an array of 300 elements. It doesn’t care if you’re accessing data of April 2015, all it cares is where in that 300 buckets do you want. So you need to convert 15840000000 (for today’s value) to a number between 0..<300.
Though I think what you really want is a Dictionary, which is also available in Swift.
Jens
10
I realize that this is not the main point of the question but:
The number of seconds since 1970 is:
1_584_000_000
which is less than UInt32.max:
4_294_967_295
Yes, you need 16 GB to store 232 elements (assuming each element has a stride of four bytes, and using binary measurement, GiB).
No, not just doubling, you'd need to double 32 times (once for each added bit), so
you'd need 68 719 476 736 GiB = 67 108 864 TiB = 64 EiB (exabytes) to store 264 elements (assuming the same element type).

EDIT:
But perhaps you meant "if you'd want to store the same number of elements, but elements being 8-byte UInt64 instead of 4-byte UInt32"? In that case you'd clearly need to double it.
Lantua
11
He actually *10 at the end, but yea.
Don’t for get that Int is 64-bit that, so double that
. Which should be 128 EiB (exbibyte). 