On Wednesday, 18 May 2016 at 03:01:14 UTC, Joakim wrote:
There is nothing "random" about increasing precision till the end, it follows a well-defined rule.

Can you please quote that well-defined rule?

It is indeed random, or arbitrary (which is the same thing):

if(x<0){
  // DMD choose 64 bit mantissa
  const float y = ...
  ...

} else {
  // DMD choose 24 bit mantissa
  float y = ...
  ...
}

How is this not arbitrary?

If x is the amplitude then a flaw like this can cause a DC offset to accumulate and you end up with reduced precision, not improved precision. A DC filter at the end does not help on this precision loss.

So you're planning on running phase-locking code partially in CTFE and runtime and it's somehow very sensitive to precision? If your "phase-locking" depends on producing bit-exact results with floating-point, you're doing it wrong.

I am not doing anything wrong. D is doing it wrong. If you add different deltas then you will get drift. So, no improved precision in calculating some deltas is not improving the accuracy. It makes it worse.

If any of this depends on comparing bit-exact floating-point results, you're doing it wrong.

It depends on the unit tests running with the exact same precision as the production code.

Fast floating point code depends on the specifics of the hardware. A system level language should not introduce a different kind of bias that isn't present in the hardware!

D is doing it wrong because it makes it is thereby forcing programmers to use algorithms that are 10-100x slower to get reliable results.

That is _wrong_.

If the constant is calculated rather than a literal, you should be checking using approxEqual.

No. 1+2+3+4 is exact on all floating point units I know of.

3. Comparing for equality is the same as subtraction followed by testing for zero.

So what?  You should be using approxEqual.

No.

So, the rule is: you shouldn't compare at all unless you know the error bounds, but that depends on WHY you are comparing.

No, you should always use error bounds. Sometimes you can get away with checking bit-exact equality, say for constants that you defined yourself with no calculation, but it's never a good practice.

It is if you know WHY you are doing a test.

Btw, have you ever tried to prove error bounds for an iterative method?
You actually think most people prove them to be correct?

Or perhaps almost all of them just pick a number out of thin air which they think will work out and rely on testing their code?

Well, the latter is no better than checking for exact equality. And I can assure you that the vast majority of programmers do not prove error bounds with the level of rigour it takes to get it correct.

The reality is that it is common practice to write code that seems to work. But that does not make it correct. However, making it correct is way too time consuming and often not worth the trouble. So people rely on testing. Floating point code is no different.

But with D semantics you cannot rely on testing. That's bad, because most people write incorrect code. Whether they are experts or not. (it is only matter of difference in frequency)

f(x) = 1/(2-x)

Should I not be able to test for the exact value "2" here?

It would make more sense to figure out what the max value of f(x) is you're trying to avoid, say 1e6, and then check for approxEqual(x, 2, 2e-6). That would make much more sense than only avoiding 2, when an x that is arbitrarily close to 2 can also blow up f(x).

I am trying to avoid an exception, not a value.

Oh, it's real world alright, you should be avoiding more than just 2 in your example above.

Which number would that be?

Simply repeating the word "random" over and over again does not make it so.

That's right. It is DMD that makes it so, not my words.

However, in order to reject what other say, you have to make an argument. And in this case we have:

1. A system level programming language that claims to excel at floating point.
2. Hardware platforms with specific behaviour.

Unfortunately 2 is true, but not 1.

D is not matching up to the minimum requirements for people wanting to write fast and reliable floating point code for a given platform.

According to the D spec, the compiler could schedule typed single precision floating point calculations to two completely different floating point units (and yes, there are platforms that provide multiple incompatible floating point units with widely differing characteristics).

That is random.
And so is "float" behaving differently than "const float".

Reply via email to