TedvG
(Ted van Gaalen)
1
in relation to my message about handling floating point number comparisation tolerance in e.g. a .stride function, wouldn't this be better handled by a compiler directive?
For example:
@floatingPointComparisonTolerance = 0.001
// all source that follows this will be compiled with this value
// until reset or another value is specified with this directive.
if fp1 == fp2 // will be evaluated with the above specified tolerance.
for v in minival.stride(to: maxival, by: 0.1)
for e from -1.0 to 123.45 by 0.1 // also in loops of course, as here in the for loop variant I will propose.
@resetFloatingPointComparisonTolerance()
At any time, you should be able to change @floatingPointComparisonTolerance,
which will have its effect on source lines that follow it.
TedvG
Joe_Groff
(Joe Groff)
2
"Floats are inaccurate, let's just add random tolerances in" is a naive outlook on floating-point numerics. There are invariants which carefully-written floating point code can expect to hold in a lot of cases. We could provide tolerant comparison operations, but global state would be a poor way of doing so, and imposing this behavior on the standard comparison operators would be problematic. It'd be better to provide methods IMO, so that e.g. `fp1.equals(fp2, tolerance: 0x1p-44)` performed a comparison with a proportional tolerance check.
-Joe
···
On Mar 1, 2016, at 10:28 AM, ted van gaalen via swift-evolution <swift-evolution@swift.org> wrote:
in relation to my message about handling floating point number comparisation tolerance in e.g. a .stride function, wouldn't this be better handled by a compiler directive?
For example:
@floatingPointComparisonTolerance = 0.001
// all source that follows this will be compiled with this value
// until reset or another value is specified with this directive.
if fp1 == fp2 // will be evaluated with the above specified tolerance.
for v in minival.stride(to: maxival, by: 0.1)
for e from -1.0 to 123.45 by 0.1 // also in loops of course, as here in the for loop variant I will propose.
@resetFloatingPointComparisonTolerance()
At any time, you should be able to change @floatingPointComparisonTolerance,
which will have its effect on source lines that follow it.
pyrtsa
(Pyry Jahkola)
3
I don't think it's a good idea. That directive would break the transitivity requirement of Equatable (the last line below):
/// **Equality is an equivalence relation**
///
/// - `x == x` is `true`
/// - `x == y` implies `y == x`
/// - `x == y` and `y == z` implies `x == z`
You might want to define another operator or function for approximately equal instead.
(Not like equality wasn't already broken for floats because of NaN, but at least we can try to keep the remaining semantics sane.)
— Pyry
···
On 01 Mar 2016, at 20:28, ted van gaalen via swift-evolution <swift-evolution@swift.org> wrote:
in relation to my message about handling floating point number comparisation tolerance in e.g. a .stride function, wouldn't this be better handled by a compiler directive?
For example:
@floatingPointComparisonTolerance = 0.001
TedvG
(Ted van Gaalen)
4
They are not random tolerances and also not global as one
can set a specific (fine tuned) tolerance bandwidth for 1 or more
statements, following such a directive, until another, or a reset.
e.g.
@floatingPointComparisonTolerance = 0.001 //tuned for a specific situation.
if a == b {} // this statement is affected..
If c != d {} // ..and also this one.
@resetFloatingPointComparisonTolerance // default is none
if a == b // here, no longer a tolerance band is active.
So, it is not global, but only in effect for statements in between/after these directives.
Nothing new here. Comparison tolerance has been in use in e.g. APL since ca 1975, see here for a good explanation.
http://microapl.com/apl_help/ch_020_070_150.htm
kind regards
TedvG
ted van gaalen
···
On 01 Mar 2016, at 21:00, Joe Groff <jgroff@apple.com> wrote:
On Mar 1, 2016, at 10:28 AM, ted van gaalen via swift-evolution <swift-evolution@swift.org> wrote:
in relation to my message about handling floating point number comparisation tolerance in e.g. a .stride function, wouldn't this be better handled by a compiler directive?
For example:
@floatingPointComparisonTolerance = 0.001
// all source that follows this will be compiled with this value
// until reset or another value is specified with this directive.
if fp1 == fp2 // will be evaluated with the above specified tolerance.
for v in minival.stride(to: maxival, by: 0.1)
for e from -1.0 to 123.45 by 0.1 // also in loops of course, as here in the for loop variant I will propose.
@resetFloatingPointComparisonTolerance()
At any time, you should be able to change @floatingPointComparisonTolerance,
which will have its effect on source lines that follow it.
"Floats are inaccurate, let's just add random tolerances in" is a naive outlook on floating-point numerics. There are invariants which carefully-written floating point code can expect to hold in a lot of cases. We could provide tolerant comparison operations, but global state would be a poor way of doing so, and imposing this behavior on the standard comparison operators would be problematic. It'd be better to provide methods IMO, so that e.g. `fp1.equals(fp2, tolerance: 0x1p-44)` performed a comparison with a proportional tolerance check.
-Joe
What about this?
infix operator ≈ {precedence 255}
func ≈ (value: Double, tolerance: Double) -> (value: Double, tolerance: Double) {
return (value: value, tolerance: tolerance)
}
func == (lhs: Double, rhs: (value: Double, tolerance: Double)) -> Bool {
return ((rhs.value - rhs.tolerance)...(rhs.value + rhs.tolerance)) ~= lhs
}
3.0 == 3.01 ≈ 0.001 // false
3.0 == 3.01 ≈ 0.01 // true
I tried using "ε", which is the standard symbol for "error", but that doesn't seem to be a valid operator character. "≈" (⌥-x, at least on a mac) is the only other one that seemed to make sense, with the possible exception of "∂", but I don't think that's as well-known.
- Dave Sweeris
···
Sent from my iPhone
On Mar 1, 2016, at 14:00, Joe Groff via swift-evolution <swift-evolution@swift.org> wrote:
On Mar 1, 2016, at 10:28 AM, ted van gaalen via swift-evolution <swift-evolution@swift.org> wrote:
in relation to my message about handling floating point number comparisation tolerance in e.g. a .stride function, wouldn't this be better handled by a compiler directive?
For example:
@floatingPointComparisonTolerance = 0.001
// all source that follows this will be compiled with this value
// until reset or another value is specified with this directive.
if fp1 == fp2 // will be evaluated with the above specified tolerance.
for v in minival.stride(to: maxival, by: 0.1)
for e from -1.0 to 123.45 by 0.1 // also in loops of course, as here in the for loop variant I will propose.
@resetFloatingPointComparisonTolerance()
At any time, you should be able to change @floatingPointComparisonTolerance,
which will have its effect on source lines that follow it.
"Floats are inaccurate, let's just add random tolerances in" is a naive outlook on floating-point numerics. There are invariants which carefully-written floating point code can expect to hold in a lot of cases. We could provide tolerant comparison operations, but global state would be a poor way of doing so, and imposing this behavior on the standard comparison operators would be problematic. It'd be better to provide methods IMO, so that e.g. `fp1.equals(fp2, tolerance: 0x1p-44)` performed a comparison with a proportional tolerance check.
-Joe
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution
Tino
(Tino)
6
I hope that I'll finally have the time to write a pitch for "inheritance for structs" this weekend — this looks like another good use case for a "newtype" feature:
struct Length: Double {
static let tolerance: Double = 0.001
}
override func ==(a: Length, b: Length) -> Bool {
return (a - b).abs() < Length.tolerance
}
Of course, this example leaves many questions, but I hope the principle is clear.
Tino
Joe_Groff
(Joe Groff)
7
They are not random tolerances and also not global as one
can set a specific (fine tuned) tolerance bandwidth for 1 or more
statements, following such a directive, until another, or a reset.
e.g.
@floatingPointComparisonTolerance = 0.001 //tuned for a specific situation.
if a == b {} // this statement is affected..
If c != d {} // ..and also this one.
@resetFloatingPointComparisonTolerance // default is none
if a == b // here, no longer a tolerance band is active.
So, it is not global, but only in effect for statements in between/after these directives.
If we literally follow the APL model, then the tolerance is global state that nonlocally changes the behavior of every operation. We don't do this kind of implicit parameterization anywhere else, and similar features have proven to be brittle to use in practice (see also, for instance, the ability for Perl and some BASIC languages to dynamically set the array index base to 0 or 1, catastrophically breaking any code you call into that expects the other base).
-Joe
···
On Mar 1, 2016, at 3:44 PM, ted van gaalen <tedvgiosdev@gmail.com> wrote:
Nothing new here. Comparison tolerance has been in use in e.g. APL since ca 1975, see here for a good explanation.
http://microapl.com/apl_help/ch_020_070_150.htm
TedvG
(Ted van Gaalen)
8
? I don't see transivity requirement broken here, because -within a comparison tolerance- they still are true.
ted van gaalen it services
Professional App development for
Apple IOS, Windows & Android
tablets and mobile phones
based on > 30 yrs of IT experience.
Web design & programming.
IBM Mainframe application programming.
www.tedvg.com
Ted F.A. van Gaalen
Hauptstr. 19/3
D-88636 Illmensee
Germany
T: 49 7558 92 17 840
M: 49 174 7707 422
···
On 01 Mar 2016, at 20:39, Pyry Jahkola <pyry.jahkola@iki.fi> wrote:
On 01 Mar 2016, at 20:28, ted van gaalen via swift-evolution <swift-evolution@swift.org> wrote:
in relation to my message about handling floating point number comparisation tolerance in e.g. a .stride function, wouldn't this be better handled by a compiler directive?
For example:
@floatingPointComparisonTolerance = 0.001
I don't think it's a good idea. That directive would break the transitivity requirement of Equatable (the last line below):
/// **Equality is an equivalence relation**
///
/// - `x == x` is `true`
/// - `x == y` implies `y == x`
/// - `x == y` and `y == z` implies `x == z`
You might want to define another operator or function for approximately equal instead.
(Not like equality wasn't already broken for floats because of NaN, but at least we can try to keep the remaining semantics sane.)
— Pyry
TedvG
(Ted van Gaalen)
9
Yes, in APL it is global, but not in what I propose for Swift here.
ted van gaalen
···
On 02 Mar 2016, at 00:48, Joe Groff <jgroff@apple.com> wrote:
On Mar 1, 2016, at 3:44 PM, ted van gaalen <tedvgiosdev@gmail.com> wrote:
They are not random tolerances and also not global as one
can set a specific (fine tuned) tolerance bandwidth for 1 or more
statements, following such a directive, until another, or a reset.
e.g.
@floatingPointComparisonTolerance = 0.001 //tuned for a specific situation.
if a == b {} // this statement is affected..
If c != d {} // ..and also this one.
@resetFloatingPointComparisonTolerance // default is none
if a == b // here, no longer a tolerance band is active.
So, it is not global, but only in effect for statements in between/after these directives.
If we literally follow the APL model, then the tolerance is global state that nonlocally changes the behavior of every operation. We don't do this kind of implicit parameterization anywhere else, and similar features have proven to be brittle to use in practice (see also, for instance, the ability for Perl and some BASIC languages to dynamically set the array index base to 0 or 1, catastrophically breaking any code you call into that expects the other base).
-Joe
Nothing new here. Comparison tolerance has been in use in e.g. APL since ca 1975, see here for a good explanation.
Quad-CT Comparison Tolerance
Joe_Groff
(Joe Groff)
10
That's cute. In a real implementation of tolerant comparison, you'd want to scale the tolerance to the magnitude of the larger operand, though. (See Essays/Tolerant Comparison - J Wiki .)
-Joe
···
On Mar 2, 2016, at 12:45 PM, David Sweeris <davesweeris@mac.com> wrote:
func == (lhs: Double, rhs: (value: Double, tolerance: Double)) -> Bool {
return ((rhs.value - rhs.tolerance)...(rhs.value + rhs.tolerance)) ~= lhs
}
3.0 == 3.01 ≈ 0.001 // false
3.0 == 3.01 ≈ 0.01 // true
I tried using "ε", which is the standard symbol for "error", but that doesn't seem to be a valid operator character. "≈" (⌥-x, at least on a mac) is the only other one that seemed to make sense, with the possible exception of "∂", but I don't think that's as well-known.
Joe_Groff
(Joe Groff)
11
This is also a place where function partial application might be interesting:
func equalityWithTolerance(tolerance: Double) -> (Double, Double) -> Bool {
return {
var exp0 = 0, exp1 = 0
frexp($0, &exp0)
frexp($1, &exp1)
return abs($0 - $1) < scalb(tolerance, max(exp0, exp1))
}
}
If you could locally bind operators, you could then do this:
func compareLengths(x: Double, y: Double) -> Bool {
let (==) = equalityWithTolerance(0x1p-44)
return x == y // Uses local (==)
}
-Joe
···
On Mar 2, 2016, at 1:23 PM, Tino Heth via swift-evolution <swift-evolution@swift.org> wrote:
I hope that I'll finally have the time to write a pitch for "inheritance for structs" this weekend — this looks like another good use case for a "newtype" feature:
struct Length: Double {
static let tolerance: Double = 0.001
}
override func ==(a: Length, b: Length) -> Bool {
return (a - b).abs() < Length.tolerance
}
Of course, this example leaves many questions, but I hope the principle is clear.
K… Does replacing my cute == function with one that accounts for everything in that link (or at least a sufficiently large subset of it) solve the problem?
···
On Mar 2, 2016, at 2:56 PM, Joe Groff <jgroff@apple.com> wrote:
On Mar 2, 2016, at 12:45 PM, David Sweeris <davesweeris@mac.com <mailto:davesweeris@mac.com>> wrote:
func == (lhs: Double, rhs: (value: Double, tolerance: Double)) -> Bool {
return ((rhs.value - rhs.tolerance)...(rhs.value + rhs.tolerance)) ~= lhs
}
3.0 == 3.01 ≈ 0.001 // false
3.0 == 3.01 ≈ 0.01 // true
I tried using "ε", which is the standard symbol for "error", but that doesn't seem to be a valid operator character. "≈" (⌥-x, at least on a mac) is the only other one that seemed to make sense, with the possible exception of "∂", but I don't think that's as well-known.
That's cute. In a real implementation of tolerant comparison, you'd want to scale the tolerance to the magnitude of the larger operand, though. (See Essays/Tolerant Comparison - J Wiki .)
-Joe
TedvG
(Ted van Gaalen)
13
Hi Joe,
to just fuzzy compare 2 floating point numbers,
the solution you describe uses
- 2 functions, with therein 6 calls to frexp, abs, max and scalb...
isn’t that overkill ?
I still think a compiler directive embedded in sources at desired locations as e.g.
@setFLoatingPointTolerance: 0.0001
.
if a == b
...
@setFloatingPointToleranceOff
…
@setFLoatingPointTolerance: 0.04
.
if temperature == roomTemperature
...
@setFloatingPointToleranceOff
So every floating point compare in source between these directives will be
will be compiled differently.
Leave it to the compiler, so no special functions/ parameters are needed,
and would be far more efficient I think.
Kind Regards
TedvG
···
On 02.03.2016, at 22:28, Joe Groff <jgroff@apple.com> wrote:
On Mar 2, 2016, at 1:23 PM, Tino Heth via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
I hope that I'll finally have the time to write a pitch for "inheritance for structs" this weekend — this looks like another good use case for a "newtype" feature:
struct Length: Double {
static let tolerance: Double = 0.001
}
override func ==(a: Length, b: Length) -> Bool {
return (a - b).abs() < Length.tolerance
}
Of course, this example leaves many questions, but I hope the principle is clear.
This is also a place where function partial application might be interesting:
func equalityWithTolerance(tolerance: Double) -> (Double, Double) -> Bool {
return {
var exp0 = 0, exp1 = 0
frexp($0, &exp0)
frexp($1, &exp1)
return abs($0 - $1) < scalb(tolerance, max(exp0, exp1))
}
}
If you could locally bind operators, you could then do this:
func compareLengths(x: Double, y: Double) -> Bool {
let (==) = equalityWithTolerance(0x1p-44)
return x == y // Uses local (==)
}
-Joe
pyrtsa
(Pyry Jahkola)
14
? I don't see transivity requirement broken here, because -within a comparison tolerance- they still are true.
Consider:
a = 1.0
b = 1.0 + 0.75 * eps
c = 1.0 + 1.5 * eps
Now,
abs(a - b) < eps, so a ~ b, and
abs(b - c) < eps, so b ~ c,
but abs(a - c) > eps, so a and c are "not close".
Joe_Groff
(Joe Groff)
15
K… Does replacing my cute == function with one that accounts for everything in that link (or at least a sufficiently large subset of it) solve the problem?
My vague preference is for named methods. In numerics-heavy domains I could see this being valuable enough to burn an operator on.
-Joe
···
On Mar 2, 2016, at 1:19 PM, davesweeris@mac.com wrote:
On Mar 2, 2016, at 2:56 PM, Joe Groff <jgroff@apple.com <mailto:jgroff@apple.com>> wrote:
On Mar 2, 2016, at 12:45 PM, David Sweeris <davesweeris@mac.com <mailto:davesweeris@mac.com>> wrote:
func == (lhs: Double, rhs: (value: Double, tolerance: Double)) -> Bool {
return ((rhs.value - rhs.tolerance)...(rhs.value + rhs.tolerance)) ~= lhs
}
3.0 == 3.01 ≈ 0.001 // false
3.0 == 3.01 ≈ 0.01 // true
I tried using "ε", which is the standard symbol for "error", but that doesn't seem to be a valid operator character. "≈" (⌥-x, at least on a mac) is the only other one that seemed to make sense, with the possible exception of "∂", but I don't think that's as well-known.
That's cute. In a real implementation of tolerant comparison, you'd want to scale the tolerance to the magnitude of the larger operand, though. (See http://code.jsoftware.com/wiki/Essays/Tolerant_Comparison .)
-Joe
Joe_Groff
(Joe Groff)
16
Hi Joe,
to just fuzzy compare 2 floating point numbers,
the solution you describe uses
- 2 functions, with therein 6 calls to frexp, abs, max and scalb...
isn’t that overkill ?
That's how APL-style tolerance is defined—the tolerance is scaled to the greater exponent of the operands. frexp, scalb, and fabs all reduce to bitwise operations on the float representation, so this should be possible to compile down to something cheap (if LLVM can't do it natively, then by hand, at least).
I still think a compiler directive embedded in sources at desired locations as e.g.
@setFLoatingPointTolerance: 0.0001
.
if a == b
...
@setFloatingPointToleranceOff
…
@setFLoatingPointTolerance: 0.04
.
if temperature == roomTemperature
...
@setFloatingPointToleranceOff
So every floating point compare in source between these directives will be
will be compiled differently.
Leave it to the compiler, so no special functions/ parameters are needed,
and would be far more efficient I think.
We don't do this anywhere else, and I'm not sure this narrow use case justifies such an invasive change to how functions work. There might be an interesting general purpose feature in supporting implicit context arguments (beyond the usual 'self' for methods).
-Joe
···
On Mar 4, 2016, at 5:11 AM, Ted F.A. van Gaalen <tedvgiosdev@gmail.com> wrote:
Another problem that I perceive with the scoped approach (and global state) is that it can't reach inside C (or Objective-C) functions.
Félix
···
Le 4 mars 2016 à 12:53:28, Joe Groff via swift-evolution <swift-evolution@swift.org> a écrit :
On Mar 4, 2016, at 5:11 AM, Ted F.A. van Gaalen <tedvgiosdev@gmail.com> wrote:
Hi Joe,
to just fuzzy compare 2 floating point numbers,
the solution you describe uses
- 2 functions, with therein 6 calls to frexp, abs, max and scalb...
isn’t that overkill ?
That's how APL-style tolerance is defined—the tolerance is scaled to the greater exponent of the operands. frexp, scalb, and fabs all reduce to bitwise operations on the float representation, so this should be possible to compile down to something cheap (if LLVM can't do it natively, then by hand, at least).
I still think a compiler directive embedded in sources at desired locations as e.g.
@setFLoatingPointTolerance: 0.0001
.
if a == b
...
@setFloatingPointToleranceOff
…
@setFLoatingPointTolerance: 0.04
.
if temperature == roomTemperature
...
@setFloatingPointToleranceOff
So every floating point compare in source between these directives will be
will be compiled differently.
Leave it to the compiler, so no special functions/ parameters are needed,
and would be far more efficient I think.
We don't do this anywhere else, and I'm not sure this narrow use case justifies such an invasive change to how functions work. There might be an interesting general purpose feature in supporting implicit context arguments (beyond the usual 'self' for methods).
-Joe
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution
TedvG
(Ted van Gaalen)
18
thanks, i see what you mean
Ted
···
On 04.03.2016, at 18:53, Joe Groff <jgroff@apple.com> wrote:
On Mar 4, 2016, at 5:11 AM, Ted F.A. van Gaalen <tedvgiosdev@gmail.com <mailto:tedvgiosdev@gmail.com>> wrote:
Hi Joe,
to just fuzzy compare 2 floating point numbers,
the solution you describe uses
- 2 functions, with therein 6 calls to frexp, abs, max and scalb...
isn’t that overkill ?
That's how APL-style tolerance is defined—the tolerance is scaled to the greater exponent of the operands. frexp, scalb, and fabs all reduce to bitwise operations on the float representation, so this should be possible to compile down to something cheap (if LLVM can't do it natively, then by hand, at least).
I still think a compiler directive embedded in sources at desired locations as e.g.
@setFLoatingPointTolerance: 0.0001
.
if a == b
...
@setFloatingPointToleranceOff
…
@setFLoatingPointTolerance: 0.04
.
if temperature == roomTemperature
...
@setFloatingPointToleranceOff
So every floating point compare in source between these directives will be
will be compiled differently.
Leave it to the compiler, so no special functions/ parameters are needed,
and would be far more efficient I think.
We don't do this anywhere else, and I'm not sure this narrow use case justifies such an invasive change to how functions work. There might be an interesting general purpose feature in supporting implicit context arguments (beyond the usual 'self' for methods).
-Joe
TedvG
(Ted van Gaalen)
19
? but it should only work on the source it compiles, not on what’s called.
TedvG
···
On 04.03.2016, at 19:22, Félix Cloutier <felixcca@yahoo.ca> wrote:
Another problem that I perceive with the scoped approach (and global state) is that it can't reach inside C (or Objective-C) functions.
Félix
Le 4 mars 2016 à 12:53:28, Joe Groff via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> a écrit :
On Mar 4, 2016, at 5:11 AM, Ted F.A. van Gaalen <tedvgiosdev@gmail.com <mailto:tedvgiosdev@gmail.com>> wrote:
Hi Joe,
to just fuzzy compare 2 floating point numbers,
the solution you describe uses
- 2 functions, with therein 6 calls to frexp, abs, max and scalb...
isn’t that overkill ?
That's how APL-style tolerance is defined—the tolerance is scaled to the greater exponent of the operands. frexp, scalb, and fabs all reduce to bitwise operations on the float representation, so this should be possible to compile down to something cheap (if LLVM can't do it natively, then by hand, at least).
I still think a compiler directive embedded in sources at desired locations as e.g.
@setFLoatingPointTolerance: 0.0001
.
if a == b
...
@setFloatingPointToleranceOff
…
@setFLoatingPointTolerance: 0.04
.
if temperature == roomTemperature
...
@setFloatingPointToleranceOff
So every floating point compare in source between these directives will be
will be compiled differently.
Leave it to the compiler, so no special functions/ parameters are needed,
and would be far more efficient I think.
We don't do this anywhere else, and I'm not sure this narrow use case justifies such an invasive change to how functions work. There might be an interesting general purpose feature in supporting implicit context arguments (beyond the usual 'self' for methods).
-Joe
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution
In particular, if you could effect how equality is defined for callee functions, you would break a lot of library code that expects equality to really be exact equality. There are a wide variety of reasons for doing this in mathematical library code (zero as a sentinel value, working around singularities that really only effect a single value, etc). Any approach to approximate equality that escapes scope would be a source of extremely hard-to-diagnose bugs.
– Steve
···
On Mar 4, 2016, at 10:28 AM, Ted F.A. van Gaalen via swift-evolution <swift-evolution@swift.org> wrote:
? but it should only work on the source it compiles, not on what’s called.
TedvG
On 04.03.2016, at 19:22, Félix Cloutier <felixcca@yahoo.ca <mailto:felixcca@yahoo.ca>> wrote:
Another problem that I perceive with the scoped approach (and global state) is that it can't reach inside C (or Objective-C) functions.
Félix
Le 4 mars 2016 à 12:53:28, Joe Groff via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> a écrit :
On Mar 4, 2016, at 5:11 AM, Ted F.A. van Gaalen <tedvgiosdev@gmail.com <mailto:tedvgiosdev@gmail.com>> wrote:
Hi Joe,
to just fuzzy compare 2 floating point numbers,
the solution you describe uses
- 2 functions, with therein 6 calls to frexp, abs, max and scalb...
isn’t that overkill ?
That's how APL-style tolerance is defined—the tolerance is scaled to the greater exponent of the operands. frexp, scalb, and fabs all reduce to bitwise operations on the float representation, so this should be possible to compile down to something cheap (if LLVM can't do it natively, then by hand, at least).
I still think a compiler directive embedded in sources at desired locations as e.g.
@setFLoatingPointTolerance: 0.0001
.
if a == b
...
@setFloatingPointToleranceOff
…
@setFLoatingPointTolerance: 0.04
.
if temperature == roomTemperature
...
@setFloatingPointToleranceOff
So every floating point compare in source between these directives will be
will be compiled differently.
Leave it to the compiler, so no special functions/ parameters are needed,
and would be far more efficient I think.
We don't do this anywhere else, and I'm not sure this narrow use case justifies such an invasive change to how functions work. There might be an interesting general purpose feature in supporting implicit context arguments (beyond the usual 'self' for methods).
-Joe
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution