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:
- Find the number of digits in 8675309
- 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
Why Does Ssl Handshake Give 'Could Not Generate Dh Keypair' Exception
What Are the Differences Between the Different Saving Methods in Hibernate
Ignoring New Fields on JSON Objects Using Jackson
Why Would You Ever Implement Finalize()
Java Resultset How to Check If There Are Any Results
Preferred Way of Loading Resources in Java
How to Sort an Arraylist in Java
How to Calculate "Time Ago" in Java
File Path to Resource in Our War/Web-Inf Folder
Process.Waitfor() Never Returns
Using Switch Statement with a Range of Value in Each Case
Eclipse Exported Runnable Jar Not Showing Images
How to Share Data with Two(2) Swingworker Class in Java
Handling Parenthesis While Converting Infix Expressions to Postfix Expressions