Moving Decimal Places Over in a Double

Moving decimal places over in a double

If you use double or float, you should use rounding or expect to see some rounding errors. If you can't do this, use BigDecimal.

The problem you have is that 0.1 is not an exact representation, and by performing the calculation twice, you are compounding that error.

However, 100 can be represented accurately, so try:

double x = 1234;
x /= 100;
System.out.println(x);

which prints:

12.34

This works because Double.toString(d) performs a small amount of rounding on your behalf, but it is not much. If you are wondering what it might look like without rounding:

System.out.println(new BigDecimal(0.1));
System.out.println(new BigDecimal(x));

prints:

0.100000000000000005551115123125782702118158340454101562
12.339999999999999857891452847979962825775146484375

In short, rounding is unavoidable for sensible answers in floating point whether you are doing this explicitly or not.


Note: x / 100 and x * 0.01 are not exactly the same when it comes to rounding error. This is because the round error for the first expression depends on the values of x, whereas the 0.01 in the second has a fixed round error.

for(int i=0;i<200;i++) {
double d1 = (double) i / 100;
double d2 = i * 0.01;
if (d1 != d2)
System.out.println(d1 + " != "+d2);
}

prints

0.35 != 0.35000000000000003
0.41 != 0.41000000000000003
0.47 != 0.47000000000000003
0.57 != 0.5700000000000001
0.69 != 0.6900000000000001
0.7 != 0.7000000000000001
0.82 != 0.8200000000000001
0.83 != 0.8300000000000001
0.94 != 0.9400000000000001
0.95 != 0.9500000000000001
1.13 != 1.1300000000000001
1.14 != 1.1400000000000001
1.15 != 1.1500000000000001
1.38 != 1.3800000000000001
1.39 != 1.3900000000000001
1.4 != 1.4000000000000001
1.63 != 1.6300000000000001
1.64 != 1.6400000000000001
1.65 != 1.6500000000000001
1.66 != 1.6600000000000001
1.88 != 1.8800000000000001
1.89 != 1.8900000000000001
1.9 != 1.9000000000000001
1.91 != 1.9100000000000001

NOTE: This has nothing to do with randomness in your system (or your power supply). This is due to a representation error, which will produce the same outcome every time. The precision of double is limited and in base 2 rather than base 10, so numbers which can be precisely represented in decimal often cann't be precisely represented in base 2.

Moving decimal place to right in c

Your problem is that float are represented internaly using IEEE-754. That is in base 2 and not in base 10. 0.25 will have an exact representation, but 0.1 has not, nor has 120.99.

What really happens is that due to floating point inacuracy, the ieee-754 float closest to the decimal value 120.99 multiplied by 100 is slightly below 12099, so it is truncated to 12098. You compiler should have warned you that you had a truncation from float to in (mine did).

The only foolproof way to get what you expect is to add 0.5 to the float before the truncation to int :

i = (f * 100) + 0.5

But beware floating point are inherently inaccurate when processing decimal values.

Edit :

Of course for negative numbers, it should be i = (f * 100) - 0.5 ...

Move decimal point in double

Simple answer is no.

Floating types can contain integer up to some arbitrary value, given by the way floats are stored. If the number is too big, it gets converted to decimal.

If you need to work with big integer values use BigInteger class.

Great tool to examine those imperfections is this float converter.
Try 123456789 in the float converter, it won't be stored exactly.

Moving a decimal point 2 places to the right?

Erm, how about multiplying by 100 before converting to text?

float final =  ( cw / q ) * 100.0;

How can I truncate a double to only two decimal places in Java?

If you want that for display purposes, use java.text.DecimalFormat:

 new DecimalFormat("#.##").format(dblVar);

If you need it for calculations, use java.lang.Math:

 Math.floor(value * 100) / 100;

How to move decimal place 2 positions to the right in SQL, not converting or rounding

Hmmm . . . I'm not sure which way you want to move it. But you can use stuff() and charindex():

select stuff(replace(str, '.', ''), charindex('.', str) + 2, 0, '.')

I'm not sure if you want + 2 or - 2, though.

So this code:

select stuff(replace(str, '.', ''), charindex('.', str) + 2, 0, '.')
from (values ('a.bcdef'), ('123.456')) v(str)

Returns:

abc.def
12345.6

This code:

select stuff(replace(str, '.', ''), charindex('.', str) - 2, 0, '.')
from (values ('abcde.f'), ('123.456')) v(str)

Returns:

abc.def
1.23456

How do I shift the decimal point in C#

The way you'd do this on paper is:

  1. Find the number of digits in 8675309
  2. Divide by 10^(number of digits)

You can find the number of digits when written as base 10 either by formatting it as a string and counting the characters (bad), or by taking the log to the base 10 and rounding it up (good):

int input = 8675309;
int numDigits = (int)Math.Ceiling(Math.Log10(input));

Then divide this by 10^numDigits:

float result = input / MathF.Pow(10, numDigits);


Related Topics



Leave a reply



Submit