user500 - 1 year ago 73

Swift Question

How to get smallest value (stride) for particular number type in Swift? I mean, the shortest non-zero stride.

For example

`1`

`Int`

`0.00...001`

`Double`

Answer Source

This has been partially addressed in separate comments already, but to bring it all together...

The smallest possible increment between distinct values is 1. This is part of the definition of an integer, so it's such a foundational aspect of the type that there isn't (and needn't be) a special API for finding it.

(One can argue that `successor`

constitutes such an API. But one can also argue that using `successor`

where you could just use `1`

makes your code much less readable.)

*There is no one smallest possible increment.* Because floating-point types use an exponent-based representation, the spacing between representable floating-point numbers varies with the exponent, as illustrated in this number line:

That image comes from What Every Computer Scientist Should Know About Floating-Point Arithmetic, an essential read for, well, everyone using floating-point numbers. You can read more about the concept in Wikipedia's pages for Unit in the Last Place and Machine Epsilon. Exploring Binary also has a good entry-level read on floating-point spacing.

Back to Swift — The `Float`

and `Double`

types conform to the `FloatingPoint`

protocol (in Swift 3, currently in beta). This defines the features of IEEE 754 floating point formats, which includes both:

The Unit in the Last Place, or

`ulp`

, which tells you the increment between a number and the next greater representable number (but for some edge cases). This is related to, but not the same as, machine epsilon, since it scales with value. (`ulpOfOne`

is the same as what other libraries call machine epsilon.)`nextUp`

and`nextDown`

, which tell you the closest greater or lesser representable numbers.

Here's an example (conveniently showing that for 32-bit `Float`

, the minimum increment gets bigger than one sooner than you might think):

```
let ichi: Float = 1.0
ichi.ulp // -> 1.192093e-07
ichi.nextUp // -> 1.00000012
let man: Float = 10_000
man.ulp // -> 10000
man.nextUp // -> 10000.001
let oku: Float = 100_000_000
oku.ulp // -> 8
oku.nextUp // -> 100000008.0
```

In Swift 2, there's no `FloatingPoint`

protocol, but you can make use of the equivalent POSIX constants/functions imported from C: `FLT_EPSILON`

and `DBL_EPSILON`

are defined as the difference between 1.0 and the next representable value, and the `nextafter`

functions find the increment at any value.