Reputation: 3272
There is a very very small negative number for example -0.123e-35
which we get from previous computing.
The number may be used in some other formulas. Is it right way to round this number suppose to ten decimal places to zero '0'?
It's all right if this number will be used just in addition operation but it will give wrong result in multiplication operation.
How right way to do it?
UPD
Why is it need to me? I realized DCT method on matrix. On test matrix 8x8 filled by '1'. I get this:
8 -7.49778027488703e-13 7.64321008887262e-13 -7.90698562193149e-13 8.26182651759402e-13 -8.78937758371177e-13 9.51152198392764e-13 -1.04158952401295e-12
-7.51721016906324e-13 1.66533453693773e-16 -2.77555756156289e-17 2.77555756156289e-17 2.77555756156289e-17 2.77555756156289e-17 -2.77555756156289e-17 1.38777878078145e-17
7.65773344411544e-13 2.77555756156289e-17 -1.38777878078145e-16 -2.77555756156289e-17 0 0 0 -1.38777878078145e-17
-7.91522860733958e-13 0 5.55111512312578e-17 -5.55111512312578e-17 -2.77555756156289e-17 -2.77555756156289e-17 -1.38777878078145e-17 -1.38777878078145e-17
8.26025642513534e-13 8.32667268468867e-17 -2.77555756156289e-17 0 0 5.55111512312578e-17 -6.93889390390723e-17 -6.93889390390723e-18
-8.78466730633572e-13 8.32667268468867e-17 -2.77555756156289e-17 -4.16333634234434e-17 1.11022302462516e-16 4.16333634234434e-17 -1.38777878078145e-17 5.55111512312578e-17
9.50946123757562e-13 -1.66533453693773e-16 -9.71445146547012e-17 2.77555756156289e-17 -9.71445146547012e-17 -1.38777878078145e-17 1.38777878078145e-17 -1.73472347597681e-17
-1.04131475783268e-12 -8.32667268468867e-17 4.16333634234434e-17 -4.16333634234434e-17 -1.38777878078145e-17 5.55111512312578e-17 2.77555756156289e-17 -4.16333634234434e-17
Also I do the same thing but in Scilab and it give me this:
8. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
as you see there are just zeros. And I want to understand may I round those very small negative numbers to zero or not?
Upvotes: 2
Views: 2638
Reputation: 222846
The information you have shown does not justify any need to round to zero. Most likely, you should simply disregard the fact that some of the results are tiny and continue with the work normally.
Perfect test data is not a good demonstration of a DCT. Real-world data rarely results in DCTs that have values that are exactly zero. Additionally, if you apply a DCT to real-world data and get a value that is small, it could be small because that is the mathematically correct result or because the mathematically correct result would be zero but there have been some errors. This means you would not have a way to determine whether a small value in the DCT results should be corrected to zero or left alone. So trying to change values to zero can actually make the data worse.
Furthermore, the small values are not likely to affect the work. Your application will use the results of the DCT to modify or analyze the signal and then will go on to perform an inverse transform or otherwise use the results. Generally, this further use will not be significantly affected by the presence of tiny errors in the data. (The errors from the microphone or other sensor or environmental noise are likely larger than these errors.)
In other words, these small values are only bothering you, the human, not the computer. Ignore them.
Upvotes: 1
Reputation: 16325
To round to 10 decimal places in JavaScript (as the question was originally tagged), simply do the following.
var num = 0.0000000000000000000000000000000000123; // 1.23e-35
num = Math.round(num * 10000000000) / 10000000000; // 0
var num = 0.000000000123; // 1.23e-10
num = Math.round(num * 10000000000) / 10000000000; // 1e-10
Please note that while the above will yield the results you're looking for, floating point values are not true decimal values, and attempting to "round" them may have unexpected results in some cases. However, this solution will ensure that any number less than 0.00000000005 will be rounded to 0, which I think is what you are looking for.
Possibly a better solution for your problem than rounding all numbers would be conditionally set the value to 0 if it's < 0.00000000005
if (num < 0.00000000005) num = 0;
Upvotes: 1
Reputation: 272517
There are lots of answers here suggesting that you do something along the lines of (x * 10^n) / 10^n
. However, this does not round to n
decimal places, in general.
Binary floating-point cannot exactly represent most finite decimal values, for example 0.1 would actually be 0.100000001490116...* So if your aim is to obtain an exact representation of a finite decimal expansion (for subsequent calculations), this approach will not work; it will merely give you the closest representable value to what you were aiming for. For exact representation, you would need to investigate a BigDecimal
library/class (the details of which will vary from language to language).
However, if you only want to display values to 10 decimal places, then your language will probably offer something similar to C's printf("%.10f\n", x);
. This really will round to 10 decimal places for display purposes.
Upvotes: 3
Reputation: 533530
The simplest way to round to N decimal places is to use round, note this returns a long
so you must divide by a double value or you can get integer division.
double rounded = Math.round(d * 1e10) / 1e10;
Using 1eN notation makes it clearer how may digits you want to round to. To ensure you don't overflow you need a bounds check.
public static double round10(double d) {
final double factor = 1e10;
return d > Long.MAX_VALUE / factor || d < -Long.MAX_VALUE / factor ?
(long) (d < 0 ? d * factor - 0.5 : d * factor + 0.5) / factor : d;
}
Here I have used casting instead of rounding as it is almost as accurate but much faster.
Upvotes: 0