I have a program in which i need to convert double 75.95 to normal integer 7595. How do I write the actual program?
My code is:
class test5 {
public static void main(String args[]) {
double d = 75.95;
System.out.println("Price before converting = "+d);
int i = (int)d;
System.out.println("(float)d = "+i);
}
}
Any particular reason why multiplying by 100 wouldn't work?
class test5 {
public static void main(String args[]) {
double d = 75.95;
System.out.println("Price before converting = "+d);
long i = Math.round(d * 100);
System.out.println("(float)d = "+i);
}
}
You have to be careful with rounding errors. See: Losing precision converting from int to double in java
Now my code is this and its working :) thanks all of you :)
class test5
{
public static void main(String args[])
{
double d = 75.95;
{
System.out.println("Price before converting = "+d);
int i = (int)(d*100);
System.out.println("Answer after converting = "+i);
}
}
}
You can multiply by a constant 100 (if there are only, and always two decimal points). If there are more, you could use String.valueOf(double) and remove the '.' and call a double a double (not a float). Something like
double d = 75.95;
// int val = (int) (d * 100); // <-- or this.
String str = String.valueOf(d).replace(".", "");
int val = Integer.valueOf(str);
System.out.printf("(double)%f = (int)%d%n", d, val);
Which outputs
(double)75.950000 = (int)7595
Related
Is there a proper way for converting a double value to a BigInteger value and later back? In the best case without loosing data. The problem is, that I don't know how many decimal places the double values have. But I need this conversion for an Algorithm which only works with non decimal values. After the Algorithm finishes I have to convert it back.
An easy example what I need: for example the sum of 2 double values but the "sum" function works only with BigInteger.
You can do it in 5 steps:
double d1 = 0.1; //your original double
BigDecimal bd1 = new BigDecimal(d1); //convert to BigDecimal
BigInteger bi = bd1.unscaledValue(); //convert to BigInteger
//here do your stuff with the BigInteger
BigDecimal bd2 = new BigDecimal(bi, bd1.scale()); //back to BigDecimal, applying scale
double d2 = bd2.doubleValue(); //convert to double
Full example applied to a sum method
Output:
0.1 + 0.1 = 0.2
0.1 + 10.1 = 10.2
0.1245 + 17.0 = 17.1245
Code:
public static void main(String[] args) {
test(0.1, 0.1);
test(0.1, 10.1);
test(0.1245, 17);
}
private static void test(double d1, double d2) {
System.out.println(d1 + " + " + d2 + " = " + sum(d1, d2));
}
private static double sum(double d1, double d2) {
BigDecimal bd1 = new BigDecimal(d1);
BigDecimal bd2 = new BigDecimal(d2);
int shift = Integer.max(bd1.scale(), bd2.scale());
BigInteger bi1 = bd1.scaleByPowerOfTen(shift).toBigInteger();
BigInteger bi2 = bd2.scaleByPowerOfTen(shift).toBigInteger();
BigInteger sum = sum(bi1, bi2);
return new BigDecimal(sum, shift).doubleValue();
}
private static BigInteger sum(BigInteger i1, BigInteger i2) {
return i1.add(i2);
}
This program is based on the BigDecimal-and-scale idea, as in assylias's answer, but modified to unconditionally use the maximum possible required scale. This allows the same scale to be used across a stream of numbers, without seeing all the numbers before processing any of them. The cost is that it will usually return unnecessarily large BigInteger values.
The scale factor, "1e1074", is based on the observation that all finite double numbers are integer multiples of Double.MIN_VALUE, which has 1074 decimal digits after the decimal point. No double can have more decimal digits after the decimal point.
import java.math.BigDecimal;
import java.math.BigInteger;
public class Test {
public static void main(String[] args) {
testit(Double.MIN_VALUE);
testit(Double.MAX_VALUE);
testit(0);
testit(1.0);
testit(Math.E);
testit(Math.PI);
}
private static void testit(double d) {
double roundTrip = scaledIntegerToDouble(doubleToScaledInteger(d));
if (d != roundTrip) {
System.out.println("ERROR: " + d + " " + roundTrip);
}
}
public static final BigDecimal scale = new BigDecimal("1e1074");
public static BigInteger doubleToScaledInteger(double d) {
BigDecimal bd = new BigDecimal(d).multiply(scale);
return bd.toBigIntegerExact();
}
public static double scaledIntegerToDouble(BigInteger bi) {
BigDecimal bd = new BigDecimal(bi).divide(scale);
return bd.doubleValue();
}
}
package test;
import java.math.*;
public class HelloWorld{
public static BigInteger sumBigInteger(BigInteger n1,BigInteger n2){
return n1.add(n2);
}
public static double sumDouble(double n1,double n2){
int scale=1;
int max = Math.max(((""+n1).split("\\."))[1].length(), ((""+n2).split("\\."))[1].length());
for (int i=0;i<max;i++) scale*=10;
BigInteger nbr1 = new BigDecimal(n1*scale).toBigInteger();
BigInteger nbr2 = new BigDecimal(n2*scale).toBigInteger();
return (sumBigInteger(nbr1,nbr2).doubleValue() / scale);
}
public static void main(String []args){
double n1=117.22 , n2=56.945;
System.out.println(n1+" + "+n2+" = "+sumDouble(n1,n2));
}
}
Output:
117.22 + 56.945 = 174.165
I have a method that is converting a decimal (double value) into a fraction and putting the numerator and denominator values into an int[] of size 2.
Testing it works out fine for most values except when I hit 0.0001. Then the return value is 1.0/1.0.
The method:
private static int[] toFractionPos(double x){
String[] parts = Double.toString(x).split("\\.");
double den = Math.pow(10, parts[1].length()); //denominator
double num = Double.parseDouble(parts[0]) * den + Double.parseDouble(parts[1]); //numerator
return reduceFraction((int)num, (int)den);
}
reduceFraction() method:
public static int[] reduceFraction(int num, int den){
int gcf = GCF(num, den); //greatest common factor
int[] rf = {num/gcf, den/gcf};
return rf;
}
Thanks!
The algorithm seems fine. However, using double is not suitable for this kind of problem, because precision decreases as the scale grows.
You should use BigDecimal and BigInteger instead. I've roughly modified your example so that it works with them, but I haven't taken care of details, i.e. parsing the String shouldn't be necessary since scale can be retrieved from a BigDecimal with a getter, you can configure different rounding modes, etc:
import java.math.BigDecimal;
import java.math.BigInteger;
public class Sample {
static int[] toFractionPos(BigDecimal x) {
String[] parts = x.toString().split("\\.");
BigDecimal den = BigDecimal.TEN.pow(parts[1].length()); // denominator
BigDecimal num = (new BigDecimal(parts[0]).multiply(den)).add(new BigDecimal(parts[1])); // numerator
return reduceFraction(num.intValue(), den.intValue());
}
static int[] reduceFraction(int num, int den) {
int gcd = BigInteger.valueOf(num).gcd(BigInteger.valueOf(den)).intValue(); // greatest
// common
// divisor
int[] rf = { num / gcd, den / gcd };
return rf;
}
public static void main(String[] args) {
int[] fraction = toFractionPos(new BigDecimal("0.0001"));
System.out.println(fraction[0] + "/" + fraction[1]); // 1/10000
}
}
Note: optimizations left as an excercise ;)
You shouldn't work with doubles as you are losing precision and this can lead to serious errors. But in the case of 1.0001 the problem is that:
Double.toString(1.0001) == "1.0E-4"
Then you try to parse "0E-4" and you get 0 instead of 1. You could do the following if you expect at most 10 decimal points:
DecimalFormat df = new DecimalFormat("0",
DecimalFormatSymbols.getInstance(Locale.ENGLISH));
df.setMaximumFractionDigits(10);
String[] parts = df.format(x).split("\\.");
How about this?
private static int[] toFractionPos(double x){
int den = (int)Math.pow(10,(int)Math.log10(Integer.MAX_VALUE));
int num = (int)(x*den);
return reduceFraction(num, den);//this came from your code
}
I think this will work,
public int[] Fraction(double n) {
BigDecimal p = BigDecimal.ONE;
BigDecimal dn = BigDecimal.valueOf(n);
while(true){
dn = dn.multiply(p);
if( dn.compareTo(new BigDecimal(dn.toBigInteger()))==0 )
break;
else
p = p.multiply(BigDecimal.TEN);
}
BigInteger num=dn.toBigInteger(), den=p.toBigInteger(), g=num.gcd(den);
num = num.divide(g);
den = den.divide(g);
int[] res = new int[2];
res[0] = num.intValue();
res[0] = den.intValue();
return res;
}
I need to convert prices into integers, like such:
(String) 12,000 to (int) 12000
245.00 to (int) 245
How can I do this?
Use NumberFormat.getCurrencyInstance():
NumberFormat nf = NumberFormat.getCurrencyInstance(); // Use Locale?
int[] ints = new int[strings.length];
for(int i = 0 ; i < strings.length ; ++i) {
ints[i] = nf.parse(strings[i]).intValue();
}
Much shorter than the other solutions:
public static int parseStringToInt(String s){
s = s.replaceAll(",", ""); //remove commas
return (int)Math.round(Double.parseDouble(s)); //return rounded double cast to int
}
Use it like so:
public static void main(String[] args) {
String[] m = {"12,000", "245.67"};
for (String s : m){
System.out.println(parseStringToInt(s));
}
}
public static int convertDoubleToInt(double d){
//rounds off to the nearest 100
long l = Math.round(d);
int i = (int) l;
return i;
}
public static double convertCommaDoubleToInt(String s) throws ParseException{
NumberFormat nf = NumberFormat.getInstance(Locale.US);
Number number = nf.parse(s);
return number.doubleValue();
}
public static void main(String[] args) throws ParseException {
String[] moneys = {"12,000", "245.76"};
for(String n: moneys){
Double d = convertCommaDoubleToInt(n);//first remove the comma, if there
System.out.println(convertDoubleToInt(d)); //then convert double into int
}
}
I'm trying to solve Project Euler problem #16, where I need to sum all the digits of 2^1000. I've gotten stuck dealing with such a big number. My program worked for any number below 10^16, but failed afterwards. This told me that my logic was correct. I went ahead and converted all variables and methods to BigDecimal, but now the program does not run properly. It compiles as it is and there is no error; it just does not terminate. Does anyone have an idea on where I went wrong here?
import java.math.BigDecimal;
import java.math.RoundingMode;
public class Powerdigitsum {
private static final BigDecimal one = new BigDecimal("1");
private static final BigDecimal ten = new BigDecimal("10");
private static BigDecimal sumofDigits(BigDecimal n){
BigDecimal sum = new BigDecimal("0");
while(n.compareTo(one) == 1 || n.compareTo(one) == 0){
sum.add(n.remainder(ten));
n.divide(ten);
n = n.setScale(0, RoundingMode.FLOOR);
}
return sum;
}
public static void main(String[] args) {
final double the_number = Math.pow(2,1000);
final double test = 15;
final BigDecimal two_to_the_thousandth_power = new BigDecimal(test);
System.out.println(sumofDigits(two_to_the_thousandth_power));
}
}
Just use BigInteger properly:
BigInteger a = new BigInteger("2").pow(1000);
The whole method is kinda wrong. See this:
private static BigInteger sumOfDigits(BigInteger n) {
BigInteger sum = BigInteger.ZERO;
while (n.compareTo(BigInteger.ZERO) == 1) {
sum = sum.add(n.remainder(ten));
n = n.divide(ten);
}
return sum;
}
You needed to compare to zero, not one. And you need to assign the values for BigIntegers and BigDecimals, their methods do nothing on their own, the instances of those classes are immutable.
For integers, it's generally better to use BigInteger. The decimal part (that gets there from dividing) is just thrown away.
final double the_number = Math.pow(2,1000);
This won't work because the_number is not large enought to take the result. You need to convert the pow call to BigInteger:
BigInteger result = new BigInteger("2").pow(1000);
But be aware.. this can take some time..
Don't use the BigDecimal(double) constructor: it is limited by the double primitive type, which cannot represent 2^1000.
You can use a BigInteger. Something along these lines should work (probably suboptimal, but...):
public static void main(final String... args)
{
// 2^1000
final BigInteger oneTo2000 = BigInteger.ONE.shiftLeft(1000);
BigInteger digitSum = BigInteger.ZERO;
// We don't want to split against the empty string, the first element would be ""
for (final String digit: oneTo2000.toString().split("(?<=.)"))
digitSum = digitSum.add(new BigInteger(digit));
System.out.println(digitSum);
}
public class SumofDigitsPow {
public static void main(String[] args) {
//2(2^1000)
String temp = BigInteger.ONE.shiftLeft(1000).toString();
int sum = 0;
for(int i=0;i<temp.length();i++){
sum+= temp.charAt(i) - '0';
}
System.out.println(Integer.toString(sum));
}
}
java.math.BigInteger.shiftLeft(int n) method returns a BigInteger whose value is (this << n),So you can get the answer by using BigInteger and LeftShift Method
import java.math.BigInteger;
public class Problem16 {
public static void main(String[] args) {
BigInteger number2 = new BigInteger("2");
BigInteger number3 = new BigInteger("0");
number3 =number2.pow(1000);
String str = number3.toString();
BigInteger sum = new BigInteger("0");
for(int i=0; i<str.length(); i++)
{
char c= str.charAt(i);
int value = Character.getNumericValue(c);
BigInteger value2 = new BigInteger(Integer.toString(value));
sum =sum.add(value2) ;
}
System.out.println(sum);
}
}
IF YOU THINK BIGINTEGER IS CHEATING AND/OR don't feel like using it/learning how to use it, this algorithm is the way to go.
Think about how you would calculate 2^1000 by hand. You'd start with 2^1 and multiply by two repeatedly. Now notice that the number of digits of powers of two increase by 1 for AT LEAST every 3 powers (could be after 4 powers like with 1024 to 8192). So make a jagged 2D array like this
int a[][]= new int[1000][];
for(int i=0;i<1000;i++)
{
a[i]= new int[1+(i/3)];
}
Then initialize a[0][0] to 2. After this, you want to write a for loop such that each row is filled from the rightmost spot. So make two variables "digit" and "carry". Digit is the number that you will input into the row you're working on, and the carry is the one you're going to take to the next calculation and add to the product of 2 and whatever digit you're multiplying it with. Be careful with the order you update digit and carry and reinitialize them to zero after every calculation. I think the hardest part is coming up with the limits for the for loop, so that it fits with the every 3 powers thing. You can make this simpler by just making a triangular jagged array that increments by one every row. I did it like this though. Here's my whole code.
import java.util.*;
public class ProjectEuler16
{
public static void main(String[] args)
{
long t1=System.currentTimeMillis();
ProjectEuler16 obj = new ProjectEuler16();
System.out.println(obj.bigNumHandler());
long t2= System.currentTimeMillis();
System.out.println(t2-t1);
}
int bigNumHandler()
{
int a[][] = new int[1000][];
for(int i=0;i<1000;i++)
{
a[i]= new int[1+(i/3)];
}
a[0][0]=2;
for(int i=1;i<1000;i++)
{
int carry=0;
int digit=0;
int f=0;
if(i%3==0)
{
f=1;
}
for(int j=a[i-1].length-1+f;j>=0;j--)
{
if(j==0&f==1)
{
a[i][0]=carry;
}
else
{
digit=((2*a[i-1][j-f])+carry)%10;
carry=((2*a[i-1][j-f])+carry)/10;
a[i][j]=digit;
}
}
}
int sum=0;
for(int k=0;k<a[999].length;k++)
{
sum=sum+a[999][k];
}
return sum;
}
}
Note that the last row lists the digits for 2^1000.I think you can figure out how to sum the digits. The program took about 5 seconds to come up with the answer.
solution::::
import java.math.BigInteger;
public class PR9 {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
BigInteger zero=BigInteger.valueOf(0);
BigInteger ten=BigInteger.valueOf(10);
BigInteger sum=zero;
BigInteger a = new BigInteger("2").pow(1000);
while(a.compareTo(zero)>0){
sum=sum.add(a.mod(ten));
a=a.divide(ten);
}
System.out.println(sum);
}
}
output:::::
1366
import java.math.BigInteger;
public class P16 {
public static BigInteger digitSum(int n) {
BigInteger sum = BigInteger.ZERO;
BigInteger number = new BigInteger("2").pow(n);
while (number.compareTo(BigInteger.ZERO) == 1) {
BigInteger remainder = number.remainder(BigInteger.TEN);
sum = sum.add(remainder);
number = number.divide(BigInteger.TEN);
}
return sum;
}
public static void main(String[] args) {
final double START = System.nanoTime();
System.out.println(digitSum(Integer.parseInt(args[0])));
final double DURATION = System.nanoTime() - START;
System.out.println("Duration: " + DURATION / 1000000 + "ms.");
}
}
While there maybe a way of solving this problem without the use of BigIntegers, it is clear that they make the code run way faster.
Mine only took about 4ms to find an answer.
should be an easy one. I originally was gonna do this in javascript but have to do it prior to setting to the form in my handler page. Anyway I need to make these values have 2 decimal places. Ex 219333.5888888 needs to be 219333.58. Is there a trim function or something?
form.setUnitRepairCost(Double.toString(jobPlanBean.getUnitTotalCost())); //UNIT REPAIR COST
form.setUnitMaterialCost(Double.toString(jobPlanBean.getUnitTotalMaterialCost())); //UNIT MATERIAL COST
here is the simple example to format the decimal value
import java.text.*;
public class DecimalPlaces {
public static void main(String[] args) {
double d = 1.234567;
DecimalFormat df = new DecimalFormat("#.##");
System.out.print(df.format(d));
}
}
multiply the double by 100.0 and cast this to an int then take that int and cast it to a double and divide by 100.0
int temp = (int)(longDouble*100.0);
double shortDouble = ((double)temp)/100.0;
public static void main(String[] args) {
double d = 6.3546;
DecimalFormat df = new DecimalFormat("#.##");
System.out.print(df.format(d));
}
For getting a double back and not a string:
double d = 80.123;
DecimalFormat df = new DecimalFormat("#.##");
double p = Double.parseDouble(df.format(d));
How about:
new java.text.DecimalFormat("0.00").format( yourNumber );
Here is String manipulation to truncate double value up to tow decimal places.
public static String truncateUptoTwoDecimal(double doubleValue) {
String value = String.valueOf(doubleValue);
if (value != null) {
String result = value;
int decimalIndex = result.indexOf(".");
if (decimalIndex != -1) {
String decimalString = result.substring(decimalIndex + 1);
if (decimalString.length() > 2) {
result = value.substring(0, decimalIndex + 3);
} else if (decimalString.length() == 1) {
result = String.format(Locale.ENGLISH, "%.2f",
Double.parseDouble(value));
}
}
return result;
}
return null;
}
As suggested by other you can use class DecimalFormat of java.text.DecimalFormat. We can also use DecimalFormat to round off decimal values.
Example:
import java.math.RoundingMode;
import java.text.DecimalFormat;
public class DecimalDemo {
private static DecimalFormat decimalFormatter = new DecimalFormat("#.##");
public static void main(String[] args) {
double number = 2.14159265359;
System.out.println("Original Number : " + number);
System.out.println("Upto 2 decimal : " + decimalFormatter.format(number)); //2.14
// DecimalFormat, default is RoundingMode.HALF_EVEN
decimalFormatter.setRoundingMode(RoundingMode.DOWN);
System.out.println("Down : " + decimalFormatter.format(number)); //2.14
decimalFormatter.setRoundingMode(RoundingMode.UP);
System.out.println("Up : " + decimalFormatter.format(number)); //2.15
}
}
Look into using a Decimal Format :
DecimalFormat twoDForm = new DecimalFormat("#.##");
By using those two methods you can handle all the exceptions also :
private String convertedBalance(String balance){
String convertedBalance = balance.toString();
Double d;
try {`enter code here`
d = Double.parseDouble(balance.toString());
Log.i("ConvertedNumber", "d (amount) = "+d.toString());
d = round(d, 2);
DecimalFormat f = new DecimalFormat("0.00");
convertedBalance = f.format(d);
Log.i("ConvertedNumber", "convertedBalance = "+convertedBalance);
}catch (NumberFormatException e){
Log.i("ConvertedNumber", "Number format exception");
}
return convertedBalance;
}
public static double round(double value, int places) {
if (places < 0) throw new IllegalArgumentException();
BigDecimal bd = new BigDecimal(value);
bd = bd.setScale(places, RoundingMode.HALF_UP);
return bd.doubleValue();
}
Yes, DecimalFormat: http://www.exampledepot.com/egs/java.text/FormatNum.html
DecimalFormat Class
public static double truncateDecimals(double d, int len) {
long p = pow(10, len);
long l = (long)(d * p);
return (double)l / (double)p;
}
public static long pow(long a, int b) {
long result = 1;
for (int i = 1; i <= b; i++) {
result *= a;
}
return result;
}
You can simply use String.format() as below.
double height = 175.8653;
System.out.println("Height is: " + String.format("%.2f", height));
This will trim the double value to two decimal places.