3

Would scaling a float value by ten to preserve precision during a calculation be always precise?

This question only applies for any number involved being less than Math.pow (2,53) and greater than Math.pow (10,-15), as Math.pow (10,16 ) > Math.pow (2,53)

I hope this clears some points

0.3 - 0.2 //0.09999999999999998

Is obvious unprecise

But doing the substraction on a scaled number

var a = 0.3;
var b = 0.2;

var l = Math.max ("".split.call(a,".")[1].length,"".split.call(b,".")[1].length);

var c;

a *= Math.pow (10,l);
b *= Math.pow (10,l);

c = a-b;

c /= Math.pow(10,l);

console.log(c); //0.1

Gives a " precise " result.

The Question is, is there any float value, matching the above mentioned criterias f<Math.pow(10,-15),when multiplied by a power of ten (where Math.pow ( 10 , n<16)<Math.pow(2,53)), which does not result in the double value nearest N(b)-N(a)?, when divided again by the same power of 10?

Like described in the snippet above.

This is only a question of interest, not about using this for actual calculations, I'm just curious

And sry for misunderstandings I`m not good in this Explanation thingy

Moritz Roessler
  • 8,542
  • 26
  • 51
  • Why not run it? It's only 9007199254740992 iterations :) – mplungjan May 23 '13 at 09:39
  • @mplungjan only if `b` is always the same number =) – Moritz Roessler May 23 '13 at 09:42
  • 1
    Lol. Math was never my forte - +1 for the interesting string casting and subsequent decimal length counting – mplungjan May 23 '13 at 09:44
  • Maybe someone who speaks better english and understood what i want to ask could rephrase parts of it to avoid misunderstandings ? =) – Moritz Roessler May 23 '13 at 11:34
  • 1
    Regarding Edit3: All non-negative powers of ten less than 2**53 are representable exactly. A proper `pow` implementation returns exact results for these cases. Consider a `double` x in which the lowest bit set has value 2**–d. The least power of ten that produces an integer when multiplied by this `double` is 10**d. If 10**d is less than 2**53 and 10**d•x is less than 2**53, then both are exactly representable. Then by the IEEE-754 specification of floating-point arithmetic, the product of 10**d and x is exact. – Eric Postpischil May 23 '13 at 19:39
  • @EricPostpischil Perfect!, could you put this into the Answer ? =) – Moritz Roessler May 23 '13 at 19:44
  • I suggest asking this in a new question instead: “Let N(x) be the value of the decimal numeral with the fewest significant digits such that x is the `double` value nearest the value of the numeral. Given `double` values a and b, how can we compute the `double` value nearest N(b)-N(a)? E.g., if a and b are the `double` values nearest .2 and .3, the desired result is the `double` value nearest .1, 0.1000000000000000055511151231257827021181583404541015625, rather than than the result of directly subtracting a and b, 0.09999999999999997779553950749686919152736663818359375.” – Eric Postpischil May 23 '13 at 19:58
  • Thanks for, the suggestion =) Thats what i'll do. I'll flag this one. – Moritz Roessler May 23 '13 at 20:09
  • I deleted my answer as it got totally spammed with comments. I don't know why one person is allowed to cause such a mess, but I don't want to take that battle by myself, and no moderator wanted to help. – Guffa May 24 '13 at 12:08
  • @Guffa That's a pity. And probably my fault as it seems i phrased my question misleading.But as suggested by Eric i asked a new [Question](http://stackoverflow.com/questions/16722996/compute-the-double-value-nearest-preferred-decimal-result), which may reflect the intent of the question a bit better, if you have an good answer to it, i would love to hear it – Moritz Roessler May 24 '13 at 13:13

1 Answers1

1

I believe the intent of the question is misdirected.

If you have some binary floating-point values a and b that you know are very near decimal numerals with a few digits, then multiplying those values by a power of ten, subtracting, and dividing by the power of ten generally does not provide a better result than simply subtracting the values directly. Each of the multiplications and divisions often introduces some rounding error, and these tend to make the final result less accurate than simply subtracting a and b directly. Thus, nothing is gained by using this roundabout method.

Since a and b already have some rounding errors (they are not exactly the numerals they are near, and it is those numerals you desire to represent), sometimes the calculated value b-a will not be the floating-point value that is nearest the difference of the decimal numerals (but it will be at most one ULP away). Infrequently, the combinations of the rounding errors in the detoured calculation will provide a result closer to that difference, but that is more a matter of happenstance (effectively chance) than of design.

Once you know the power of 10 involved, p, you could get this best possible result by calculating Math.round((b-a)*p)/p, provided the numbers involved are sufficiently small that the rounding error in (b-a)*p is always less than .5.

Regardless, it is likely neither approach is a good way to design your calculations.

Regarding Edit3: All non-negative powers of ten less than 253 are representable exactly. A proper pow implementation returns exact results for these cases. Consider a double x in which the lowest bit set has value 2–d. The least power of ten that produces an integer when multiplied by this double is 10d. If 10d is less than 253 and 10d•x is less than 253, then both are exactly representable. Then by the IEEE-754 specification of floating-point arithmetic, the product of 10d and x is exact.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • Thanks for the comment and the Answer =) Regarding your comment, i updated the question. But either i got your answer wrong, or you my question, as this still does not answer the question for me, what i meant is, is there **any** float value, matching the in the Question mentioned criterias *`f – Moritz Roessler May 23 '13 at 19:26
  • It`snot that I actually want to do calculations with it. It's rather a question of curiosity :) – Moritz Roessler May 23 '13 at 19:34
  • @C5H8NNaO4: I answered Edit3 in a comment. However, this is essentially useless for the purposes you have described. In order to “multiply by 10 until you get an integer”, you have to multiply by the number of bits from the 2**–1 bit to the least valued set bit. This is usually different from the number of *decimal* digits one might associate with the number. E.g., for “1.15”, it requires 10**51, not 10**2. – Eric Postpischil May 23 '13 at 19:44
  • Thanks for the comment, that Answered my question =) And I simplified the Question to the comment above. – Moritz Roessler May 23 '13 at 19:54