Decimal point control - java

I doing a program that will print out the sum and average of a set of numbers. I'm pretty new to java, and I can't seem to figure out how to get the .7 that is supposed to be on the end of the average, I only get .0. I don't think it has to do with my math, I think there is an error in my rounding statement. Could someone point the error out to me? Thanks guys.
public class Program
{
public static void main (String[]args)
{
int a = 475;
int b = 821;
int c = 369;
int d = 562;
int e = a+b+c+d;
double f = e/4;
f=(int)(f*10+.5)/10;
System.out.println("The sum of the four numbers is "+ e + " and the average is "+ f);
}
}

Instead of double f = e/4;, do double f = e/4.0;
With e/4, you divide an int by an int, which results in an int. The result is afterwards assigned to a double. That's why you don't get decimals in your result.
With e/4.0, you divide an int by a double, which results in a double.

You lost the decimal point because e/4 is an integer. try e/4F to indicate the expression as float number
double f = e/4F;

When you have an integer divide by another integer, this is call integer division. The output will the discard the decimal values.
For example:
double v1 = 5/2; //Value of v1: 2.0 (0.5 discarded)
double v2 = 10/3; //Value of v2: 3.0 (0.333 discarded)
An integer division is happening in your codes at this line:
double f = e/4;
Hence, all the decimal values are discarded.
To retain the decimal value, you can simply do one the following (to indicate one of the operand is a decimal value, hence integer division will not occur):
double f = e/4.0;
double f = e/(double)4;
double f = e/4d;

Related

How to move the digit in a double to the end without converting to string in Java

I am trying to make my number move the first character to the end.
For example I would have my double d.
double d = 12345.6;
double result = 2345.61;
Currently I am removing the first character of d with:
d = d % (int) Math.pow(10, (int) Math.log10(d));
But I do not know how to store the character I am removing so I could put it at the end. I know I could just convert d into an array or a string, but I want to keep it as a double if at all possible.
I am getting my double from a nanosecond clock using Instant.now, so I can guarantee it starts as an 8 digit positive int, which I start by adding .0 to so I can make it a double. I know I can just use string (as I mentioned in the post), but I was wondering if there was a way to do it without conversions.
Thanks for helping!
(this is my first post I apologize if it is bad)
This is a pretty tough problem, and this isn't a working answer but it is pretty close. The only trouble I ran into was java adding decimals to the end of my doubles because it can't represent a number very well. My solution might get you on the right path. The appendChar was messing up because it was adding digits to the end of the double, other than that problem this would have worked.
public static void main(String[] args) {
double test = 4234.1211;
boolean hasDecimals = test % 1 > 0;
double[] leadChar = getLeadDigitAndMulti(test);
double appendedValue = appendLeadChar(test, (int) leadChar[1], hasDecimals);
}
public static double[] getLeadDigitAndMulti(double value) {
double[] result = new double[2];
int multiplier = 10;
int currentMultiplier = 1;
while (value > currentMultiplier) {
currentMultiplier *= multiplier;
}
currentMultiplier /= multiplier;
double trail = value % (currentMultiplier);
result[0] = currentMultiplier;
double lead = value - trail;
lead /= currentMultiplier;
result[1] = lead;
return result;
}
public static double appendLeadChar(double value, int leadChar, boolean hasDecimals) {
if (!hasDecimals) {
return (value * 10) + leadChar;
}
int multiplier = 10;
double currentMultiplier = 1;
while (value > 0) {
value %= currentMultiplier;
currentMultiplier = currentMultiplier / multiplier;
}
return 0;
}
I would start with at least figuring out how many digits long your double is. I'm not too sure of how to make it work but I saw another question that would answer it. Here is the link to that thread:
Number of decimal digits in a double
And the closest code on there that I could find to find the length would be:
double d= 234.12413;
String text = Double.toString(Math.abs(d));
int integerPlaces = text.indexOf('.');
int decimalPlaces = text.length() - integerPlaces - 1;
NOTE THIS SEGMENT OF CODE IS NOT MINE, credit goes to Peter Lawrey who originally answered this in the linked thread.
Then using code or modified code similar to above ^ assuming you would find how to find the length of the double or the total number of digits of your double, you would create a new int or double variable that would store the double and round it using BigDecimal to the highest place value. The place that the BigDecimal will round to will be set using a 10*pow(x) where x is the number of places AFTER the decimal.
Sorry I am unable to provide code on how to make this actually run because I am pretty new to java. Here is what I mean in more detailed pseudocode:
double d = 12345.6; //the double you are evaluating
double dNoDecimal; //will be rounded to have no decimal places in order to calculate place of the 1st digit
double dRoundedFirstDigit; //stores the rounded number with only the 1st digit
double firstDigit; //stores first digit
dNoDecimal = d; //transfers value
dNoDecimal = [use BigDecimal to round so no decimal places will be left]
//dNoDecimal would be equal to 12345 right now
[use above code to find total amount of place values]
[knowing place values use BigDecimal to round and isolate 1st digit of double]
dRoundedFirstDigit = dNoDecimal; //transfers value
dRoundedFirstDigit = [round using BigDecimal to leave only 1st digit]
firstDigit = [dRoundedFirstDigit cut down to 1st digit value using length found from before, again an equation will be needed]
//Now use reverse process
//do the same thing as above, but find the number of decimals by rounding down to leave only decimals (leaving only .6)
//find the length
//use length to calculate what to add to the original value to move the digit to the end (in this case would be d += firstDigit*Math.pow(10,-2))
I apologize if I just made everything seem more confusing, but I tried my best, hope this helps.
Also, doing this without an array or string is really difficult... may I ask why you need to do it without one?

Get a numer decimal part as Integer using only math

Edit: This has to do with how computers handle floating point operations, a fact that every programmer faces once in a lifetime. I didn't understand this correctly when I asked the question.
I know the simplest way to start dealing with this would be:
val floatNumber: Float = 123.456f
val decimalPart = floatNumber - floatNumber.toInt() //This would be 0.456 (I don't care about precision as this is not the main objective of my question)
Now in a real world with a pen and a piece of paper, if I want to "convert" the decimal part 0.456 to integer, I just need to multiply 0.456 * 1000, and I get the desired result, which is 456 (an integer number).
Many proposed solutions suggest splitting the number as string and extracting the decimal part this way, but I need the solution to be obtained mathematically, not using strings.
Given a number, with an unknown number of decimals (convert to string and counting chars after . or , is not acceptable), I need to "extract" it's decimal part as an integer using only math.
Read questions like this with no luck:
How to get the decimal part of a float?
How to extract fractional digits of double/BigDecimal
If someone knows a kotlin language solution, it would be great. I will post this question also on the math platform just in case.
How do I get whole and fractional parts from double in JSP/Java?
Update:
Is there a "mathematical" way to "calculate" how many decimals a number has? (It is obvious when you convert to string and count the chars, but I need to avoid using strings) It would be great cause calculating: decimal (0.456) * 10 * number of decimals(3) will produce the desired result.
Update 2
This is not my use-case, but I guess it will clarify the idea:
Suppose you want to calculate a constant(such as PI), and want to return an integer with at most 50 digits of the decimal part of the constant. The constant doesn't have to be necessarily infinite (can be for example 0.5, in which case "5" will be returned)
I would just multiply the fractional number by 10 (or move the decimal point to the right) until it has no fractional part left:
public static long fractionalDigitsLong(BigDecimal value) {
BigDecimal fractional = value.remainder(BigDecimal.ONE);
long digits;
do {
fractional = fractional.movePointRight(1); // or multiply(BigDecimal.TEN)
digits = fractional.longValue();
} while (fractional.compareTo(BigDecimal.valueOf(digits)) != 0);
return digits;
}
Note 1: using BigDecimal to avoid floating point precision problems
Note 2: using compareTo since equals also compares the scale ("0.0" not equals "0.00")
(sure the BigDecimal already knows the size of the fractional part, just the value returned by scale())
Complement:
If using BigDecimal the whole problem can be compressed to:
public static BigInteger fractionalDigits(BigDecimal value) {
return value.remainder(BigDecimal.ONE).stripTrailingZeros().unscaledValue();
}
stripping zeros can be suppressed if desired
I am not sure if it counts against you on this specific problem if you use some String converters with a method(). That is one way to get the proper answer. I know that you stated you couldn't use String, but would you be able to use Strings within a Custom made method? That could get you the answer that you need with precision. Here is the class that could help us convert the number:
class NumConvert{
String theNum;
public NumConvert(String theNum) {
this.theNum = theNum;
}
public int convert() {
String a = String.valueOf(theNum);
String[] b = a.split("\\.");
String b2 = b[1];
int zeros = b2.length();
String num = "1";
for(int x = 0; x < zeros; x++) {
num += "0";
}
float c = Float.parseFloat(theNum);
int multiply = Integer.parseInt(num);
float answer = c - (int)c;
int integerForm = (int)(answer * multiply);
return integerForm;
}
}
Then within your main class:
public class ChapterOneBasics {
public static void main(String[] args) throws java.io.IOException{
NumConvert n = new NumConvert("123.456");
NumConvert q = new NumConvert("123.45600128");
System.out.println(q.convert());
System.out.println(n.convert());
}
}
output:
45600128
456
Float or Double are imprecise, just an approximation - without precision. Hence 12.345 is somewhere between 12.3449... and 12.3450... .
This means that 12.340 cannot be distinghuished from 12.34. The "decimal part" would be 34 divided by 100.
Also 12.01 would have a "decimal part" 1 divided by 100, and too 12.1 would have 1 divided by 10.
So a complete algorith would be (using java):
int[] decimalsAndDivider(double x) {
int decimalPart = 0;
int divider = 1;
final double EPS = 0.001;
for (;;) {
double error = x - (int)x;
if (-EPS < error && error < EPS) {
break;
}
x *= 10;
decimalPart = 10 * decimalPart + ((int)(x + EPS) % 10);
divider *= 10;
}
return new int[] { decimalPart, divider };
}
I posted the below solution yesterday after testing it for a while, and later found that it does not always work due to problems regarding precision of floats, doubles and bigdecimals. My conclusion is that this problem is unsolvable if you want infinite precision:
So I re-post the code just for reference:
fun getDecimalCounter(d: Double): Int {
var temp = d
var tempInt = Math.floor(d)
var counter = 0
while ((temp - tempInt) > 0.0 ) {
temp *= 10
tempInt = Math.floor(temp)
counter++
}
return counter
}
fun main(args: Array <String> ) {
var d = 3.14159
if (d < 0) d = -d
val decimalCounter = getDecimalCounter(d)
val decimalPart = (d - Math.floor(d))
var decimalPartInt = Math.round(decimalPart * 10.0.pow(decimalCounter))
while (decimalPartInt % 10 == 0L) {
decimalPartInt /= 10
}
println(decimalPartInt)
}
I dropped floats because of lesser precision and used doubles.
The final rounding is also necessary due to precision.

How does Automatic conversion works in java?

So i had this exercise to add first seven terms from 1 to 7 in order like 1/1!+2/2!+3/3!........7/7!. Below is my code:
public class Problem9
{
public static void main(String args[])
{
int num, i;
float result = 1.0f;
for(num=2; num<=4; num++)
{
i =num;
int fact_num=1;
while(i>=1)
{
fact_num = i*fact_num;
i--;
}
System.out.println("num = "+num);
System.out.println("fact = "+fact_num);
result = result+ (float)num/fact_num;// This line is the one i m
// talking about
}
System.out.printf("The result = %.3f ",result);
}
}
So what is the difference between following line
result = result+ (float)num/fact_num;
and
result = result+ (float)(num/fact_num);
How is the conversion working here.
(float)(num/fact_num) performs int division and casts the result to float, which means that if num < fact_num, the result would be 0.0.
(float)num/fact_num casts num to float and performs floating point division, which means the result won't be 0.0 if num < fact_num (unless num is 0 of course). This is the form you should use in your code, since you are performing divisions whose results are smaller than 1, so int division won't give you the correct result.
(float)(num/fact_num);
Means the result of the two integer divisions casts into a float. The final answer will be a float.
(float)num/fact_num;
Here the int num is cast into a float. the divided by an integer.
For example :
int num = 5;
int fact_num = 2;
System.out.println((float)(num/fact_num));
will give an output of:
2.0

java program using int and double

I have written a simple Java program as shown here:
public class Test {
public static void main(String[] args) {
int i1 =2;
int i2=5;
double d = 3 + i1/i2 +2;
System.out.println(d);
}
}
Since variable d is declared as double I am expecting the result of this program is 5.4 but I got the output as 5.0
Please help me in understanding this.
i1/i2 will be 0. Since i1 and i2 are both integers.
If you have int1/int2, if the answer is not a perfect integer, the digits after the decimal point will be removed. In your case, 2/5 is 0.4, so you'll get 0.
You can cast i1 or i2 to double (the other will be implicitly converted)
double d = 3 + (double)i1/i2 +2;
i1/i2 when converted to int gives 0. ie. why you are getting 5.0. Try this :
public static void main(String args[])
{
int i1 =2;
int i2=5;
double d = 3 + (double)i1/(double)i2 +2;
System.out.println(d);
}
This line is done in parts:
double d = 3 + i1/i2 +2;
double d = 3 + (i1/i2) +2;
double d = 3 + ((int)2/(int)3) +2;
double d = 3 + ((int)0) +2;
double d = (int)5;
double d = 5;
The double just means that the answer will be cast to a double, it doesn't have any effect till the answer is computed. You should write
double d = 3d + (double)i1/i2 +2d; //having one double in each "part" of the calculation will force it to use double maths, 3d and 2d are optional
i1/i2 will be 0 because both i1 and 12 are integers.
if you cast i1 or i2 to double then it will give the desired output.
double d = 3 + (double)i1/i2 +2;
This link provides information about data type conversion, both implicit and explicit type.
To provide exact answer to the question will be :
double d = 3 + (double)i1/i2 + 2
int i1 =2;
int i2=5;
double d = 3 + (double)i1/(double)i2 +2;
if i1/i2 will be fractional value then double will help it to be in fraction instead of int.
so now you will the result as you want. or you can also use following code
double d = 3+(double)i1/i2+2;
In this line i1 is converted into double which will be divided with i2 and result will be in double, so again result will be as 5.4
Since i1=2 and i2=5 are integer type and when you divide (2/5) them, It gives integer value (0) because fractional part(.4) get discarded.
So put (double)i1/i2 on the equation.

Integer or double return value

I have an Integer value been passed in and then it is divided by 100, so result could either be an int or double so not sure if cast it or not.
public void setWavelength(Integer value) {
this.wavelength = value;
}
then value divided by 100
pluggable.setWavelength(entry.getPluggableInvWavelength()/100);
So not sure how to cast this value/object
If you divide an integer (int) by an other integer (int) the result will be an integer (int) again.
-- More details: 15.17 Multiplicative Operators
You need to mark one or both as double
//cast the divisor entry.getPluggableInvWavelength() to double
pluggable.setWavelength( ((double) entry.getPluggableInvWavelength()) /100);
or
//make the constant quotient a double
pluggable.setWavelength(entry.getPluggableInvWavelength() /100.0);
Pay attention to the fact, that java.lang.Integer is a immutable wrapper type and not an int! - In fact you can not calculate with java.lang.Integer, but since Java 1.5 the compiler will convert int to Integer and back automatically (auto boxing and auto unboxing). But in general it is better to understand the difference and use Integer only if you real need objects (and not numbers to calculate).
If waveLength is double, then have:
entry.getPluggableWavelength() / 100d;
d means that the number is treated as double, and hence the division result is double.
If you divide an int by an int, you always get an int. If you want a float or a double (because you need to represent fractional parts of the result), then you'll need to cast one or both inputs:
int a = 3;
int b = 4;
int c1 = a / b; // Equals 0
double c2 = a / b; // Still equals 0
double c3 = (double)a / (double)b; // Equals 0.75
if entry.getPluggableInvWavelength() returnsd an int the results of /100 will also be an int
If you have to have a double result, then you must store a double result.
double wavelength;
public void setWavelength(double value) {
this.wavelength = value;
}
pluggable.setWavelength(entry.getPluggableInvWavelength()/100.0);
Dividing by 100.0 is all you need to have a double result with 2 decimal places.

Categories