[swift-evolution] Strider with 'from', 'to', 'by 'and 'tolerance' parameters .
Ted F.A. van Gaalen
tedvgiosdev at gmail.com
Thu Mar 3 17:05:56 CST 2016
Hello.
P R E L I M I N A R Y
I have made a strider as described here:
it has been built in playground.
// Implementation of a strider function
// with *from* *to* *by* and *tolerance* values
/// StriderGenerator
/// constructor parms:
/// from: start value.
/// to: end value.
/// by: stepping value.
/// tolerance: this should be a value that makes sense in relation to the range magnitude.
/// Functional description:
/// Strides through a range, bounded by 'from' and 'to', moving with the amount in 'by'.
/// A tolerance value is applied with bounds-testing because floating point numbers have a finite
/// precision, due to storage limitations of today's computers.
/// Note that it is also possibe to move backwards e.g.
/// for val in 10.0.strider(to: -10 , by: 0.5, tolerance: 0.0001)
///
/// made by Ted van Gaalen, based upon previously existing examples of strider variants
/// as found in swift-evolution.org
/// 3.3.2016
///
/// This code runs OK in Xcode Playground, however:
/// WARNING! This code has yet to be tested more thoroughly before applying/installing it!
///
public struct StriderGenerator : GeneratorType
{
private let low: Double
private let high: Double
private var step : Double
private var tol : Double
private var iterator = 0
private let moveForward: Bool
private var done = false
public init(from: Double, to: Double, by: Double, tolerance: Double)
{
step = by
if from < to
{
low = from
high = to
moveForward = true
}
else
{
low = to
high = from
moveForward = false
}
self.tol = tolerance * 0.5 // center it.
}
/// return next value or nil, if no next
/// element exists.
public mutating func next() -> Double?
{
let current:Double
if done
{
return nil
}
if moveForward
{
current = low + Double(iterator) * step
}
else
{
current = high - Double(iterator) * step
}
iterator += 1
// done if exceeding low or highlimits + tolerance
done = current > high + tol ||
current < low - tol
if done
{
return nil
}
else
{
return current
}
}
}
public struct Strider : SequenceType // Aragorn
{
private let start: Double
private let end: Double
private let step: Double
private let tol: Double
init(from: Double, to: Double, by: Double, tolerance : Double)
{
_precondition(by > 0.0 ,
"Init of struct Strider: 'by:...' value must be > 0.0.")
_precondition(abs(by) > tolerance,
"Init of struct Strider: 'by:...' value must be > tolerance.")
_precondition(tolerance >= 0.0,
"Init of struct Strider: tolerance:... value must be >= 0.0")
start = from
end = to;
step = by
tol = tolerance
}
/// Return a *generator* over the elements of this *sequence*.
public func generate() -> StriderGenerator
{
return StriderGenerator(from: start, to: end, by: step, tolerance: tol)
}
}
public extension Double
{
public func strider(to to: Double, by: Double, tolerance: Double ) -> Strider
{
return Strider( from: self, to: to, by: by, tolerance: tolerance)
}
}
print("Testing the new .strider extension")
let testvalues =
[
// fr: to: by: tolerance:
[ 0.0, 5.0, 1.0, 0.0 ],
[-3.0, 4.0, 0.12, 0.1 ],
[ 2.0, -1.0, 0.34, 0.1 ],
[ 0.001, -0.002, 0.0001, 0.00001 ]
]
for parm in testvalues
{
print("==============Stride from: \(parm[0]) to: \(parm[1]) by: \(parm[2]) tolerance: \(parm[3])\n")
for val in parm[0].strider(to: parm[1], by: parm[2], tolerance: parm[3])
{
print("\(val) ", terminator:"")
}
print("\n\n")
}
Hereunder are a few test results from the above code running in Xcode Playground,
More testing is needed (anyone ?),
just fill up the 2d array ‘testvalues'
Of course suggestions for improvements are welcome.
Kind Regards from a Dutch programmer who lives in southern Germany
TedvG
==============Stride from: 0.0 to: 5.0 by: 1.0 tolerance: 0.0
0.0 1.0 2.0 3.0 4.0 5.0
==============Stride from: -3.0 to: 4.0 by: 0.12 tolerance: 0.1
-3.0 -2.88 -2.76 -2.64 -2.52 -2.4 -2.28 -2.16 -2.04 -1.92 -1.8 -1.68 -1.56 -1.44 -1.32 -1.2 -1.08 -0.96 -0.84 -0.72 -0.6 -0.48 -0.36 -0.24 -0.12 0.0 0.12 0.24 0.36 0.48 0.6 0.72 0.84 0.96 1.08 1.2 1.32 1.44 1.56 1.68 1.8 1.92 2.04 2.16 2.28 2.4 2.52 2.64 2.76 2.88 3.0 3.12 3.24 3.36 3.48 3.6 3.72 3.84 3.96
==============Stride from: 2.0 to: -1.0 by: 0.34 tolerance: 0.1
2.0 1.66 1.32 0.98 0.64 0.3 -0.04 -0.38 -0.72
==============Stride from: 0.001 to: -0.002 by: 0.0001 tolerance: 1e-05
0.001 0.0009 0.0008 0.0007 0.0006 0.0005 0.0004 0.0003 0.0002 9.99999999999999e-05 0.0 -0.0001 -0.0002 -0.0003 -0.0004 -0.0005 -0.0006 -0.0007 -0.0008 -0.0009 -0.001 -0.0011 -0.0012 -0.0013 -0.0014 -0.0015 -0.0016 -0.0017 -0.0018 -0.0019 -0.002
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160304/d654d1f4/attachment-0001.html>
More information about the swift-evolution
mailing list