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