Ah, I see.

So, here's my issue. I recently ported some C code for satellite position 
prediction to Swift. This code used fmod() a lot. I had thought fmod() was just 
% for floats, but I see now it's not.

What is truncatingRemainder in all this? It would be great if there were a 
documentation section covering this in detail (in the context of Swift). It's 
confusing because fmod() is available, but so are the other options.

Should %% be something the language provides for IEEE 754 remainder()?



> On Nov 9, 2017, at 11:18 , Stephen Canon <sca...@apple.com> wrote:
> 
>> On Nov 9, 2017, at 10:55 AM, Rick Mann via swift-users 
>> <swift-users@swift.org> wrote:
>> 
>> Why is % not available for floating point numbers?
> 
> This has been discussed extensively. Swift had this this operator originally, 
> but we removed it. Here’s the rationale I gave back then:
> 
> -----------
> 
> While C and C++ do not provide the “%” operator for floating-point types, 
> many newer languages do (Java, C#, and Python, to name just a few).  
> Superficially this seems reasonable, but there are severe gotchas when % is 
> applied to floating-point data, and the results are often extremely 
> surprising to unwary users.  C and C++ omitted this operator for good reason. 
>  Even if you think you want this operator, it is probably doing the wrong 
> thing in subtle ways that will cause trouble for you in the future.
> 
> The % operator on integer types satisfies the division algorithm axiom: If b 
> is non-zero and q = a/b, r = a%b, then a = q*b + r.  This property does not 
> hold for floating-point types, because a/b does not produce an integral 
> value.  If it did produce an integral value, it would need to be a bignum 
> type of some sort (the integral part of DBL_MAX / DBL_MIN, for example, has 
> over 2000 bits or 600 decimal digits).
> 
> Even if a bignum type were returned, or if we ignore the loss of the division 
> algorithm axiom, % would still be deeply flawed.  Whereas people are 
> generally used to modest rounding errors in floating-point arithmetic, 
> because % is not continuous small errors are frequently enormously magnified 
> with catastrophic results:
> 
>       (swift) 10.0 % 0.1
>     // r0 : Double = 0.0999999999999995 // What?!
> 
> [Explanation: 0.1 cannot be exactly represented in binary floating point; the 
> actual value of “0.1” is 
> 0.1000000000000000055511151231257827021181583404541015625.  Other than that 
> rounding, the entire computation is exact.]
> 
> Proposed Approach:
> Remove the “%” operator for floating-point types.
> 
> Alternative Considered:
> Instead of binding “%” to fmod( ), it could be bound to remainder( ), which 
> implements the IEEE 754 remainder operation; this is just like fmod( ), 
> except instead of returning the remainder under truncating division, it 
> returns the remainder of round-to-nearest division, meaning that if a and b 
> are positive, remainder(a,b) is in the range [-b/2, b/2] rather than [0, b).  
> This still has a large discontinuity, but the discontinuity is moved away 
> from zero, which makes it much less troublesome (that’s why IEEE 754 
> standardized this operation):
> 
>       (swift) remainder(1, 0.1)
>     // r1 : Double = -0.000000000000000055511151231257827 // Looks like 
> normal floating-point rounding
> 
> The downside to this alternative is that now % behaves totally differently 
> for integer and floating-point data, and of course the division algorithm 
> still doesn’t hold.
> 
> 


-- 
Rick Mann
rm...@latencyzero.com


_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

Reply via email to