my math is broken on TextView - java

To be honest I've just started with programming but for the life of me I can't figure out where I'm wrong.
the math is:
10$ / 2 hours
tips per hour = 5 (i get 0.2)
waiter 1 pay = 10 (i get 0.4?)
screenshot
The Calculation in MainActivity:
double resultTotalHours = cWaiter1Hours + cWaiter2Hours + cWaiter3Hours + cWaiter4Hours;
double calcTipsPerHour = resultTotalHours / totalTips;
double resultBarsCut = (totalTips * (cBarCutInput / 100));
double resultTaxDeposit = resultTotalHours * 3;
double resultTipsPerHour = (totalTips - resultBarsCut - resultTaxDeposit) / resultTotalHours;
double resultWaiter1Pay = cWaiter1Hours * resultTipsPerHour;
double resultWaiter2Pay = cWaiter2Hours * resultTipsPerHour;
double resultWaiter3Pay = cWaiter3Hours * resultTipsPerHour;
double resultWaiter4Pay = cWaiter4Hours * resultTipsPerHour;
double resultWaiter1NoTax = cWaiter1Hours * calcTipsPerHour;
double resultWaiter2NoTax = cWaiter2Hours * calcTipsPerHour;
double resultWaiter3NoTax = cWaiter3Hours * calcTipsPerHour;
double resultWaiter4NoTax = cWaiter4Hours * calcTipsPerHour;
Casting the results to the TextViews:
if (calcTipsPerHour <= 30) {
totalHoursView.setText(Double.toString(resultTotalHours));
tipsPerHourView.setText(Double.toString(calcTipsPerHour));
barsCutView.setText(Double.toString(0));
taxDepositView.setText(Double.toString(0));
waiter1Pay.setText(Double.toString(resultWaiter1NoTax));
waiter2Pay.setText(Double.toString(resultWaiter2NoTax));
waiter3Pay.setText(Double.toString(resultWaiter3NoTax));
waiter4Pay.setText(Double.toString(resultWaiter4NoTax));
} else {
totalHoursView.setText(Double.toString(resultTotalHours));
tipsPerHourView.setText(Double.toString(resultTipsPerHour));
barsCutView.setText(Double.toString(resultBarsCut));
taxDepositView.setText(Double.toString(resultTaxDeposit));
waiter1Pay.setText(Double.toString(resultWaiter1Pay));
waiter2Pay.setText(Double.toString(resultWaiter2Pay));
waiter3Pay.setText(Double.toString(resultWaiter3Pay));
waiter4Pay.setText(Double.toString(resultWaiter4Pay));
}

The problem is here:
double calcTipsPerHour = resultTotalHours / totalTips;
This is currently doing 2 / 10 = 0.2.
You want to do the reciprocal:
double calcTipsPerHour = totalTips / resultTotalHours;
This should also fix your waiter's pay

You put hours in the numerator and tips in the denominator so you are getting the inverse of what you want: hours/tip
What you want is:
double calcTipsPerHour = totalTips / resultTotalHours;

Related

Generate a random geopoint from a fixed distance from a given latitude and longitude

I am writing a java program to generate a all the longitude and latitude with a fixed distance from my my given point. the distance must be exact 2000km, not withub 2000km.
this is my code
public static void getLocation(double x0, double y0, int meters) {
Random random = new Random();
// Convert radius from meters to degrees
double radiusInDegrees = meters / 111000f;
double u = random.nextDouble();
double v = random.nextDouble();
double w = radiusInDegrees * Math.sqrt(u);
double t = 2 * Math.PI * v;
double x = w * Math.cos(t);
double y = w * Math.sin(t);
// Adjust the x-coordinate for the shrinking of the east-west distances
// double new_x = x / Math.cos(Math.toRadians(y0));
double foundLongitude = x + x0;
double foundLatitude = y + y0;
System.out.println("Longitude: " + foundLongitude + " Latitude: " + foundLatitude );
}
How do I make all the point generate equal distance from the geo point, like forming a circle?
public static void generatePoint(double latitude, double longitude, double distanceInMetres, double bearing) {
Random random = new Random();
//int bear = random.nextInt(360);
double brngRad = Math.toRadians(bearing);
double latRad = Math.toRadians(latitude);
double lonRad = Math.toRadians(longitude);
int earthRadiusInMetres = 6371000;
double distFrac = distanceInMetres / earthRadiusInMetres;
double latitudeResult = Math.asin(Math.sin(latRad) * Math.cos(distFrac) + Math.cos(latRad) * Math.sin(distFrac) * Math.cos(brngRad));
double a = Math.atan2(Math.sin(brngRad) * Math.sin(distFrac) * Math.cos(latRad), Math.cos(distFrac) - Math.sin(latRad) * Math.sin(latitudeResult));
double longitudeResult = (lonRad + a + 3 * Math.PI) % (2 * Math.PI) - Math.PI;
System.out.println("bearing: "+bearing+ ", latitude: " + Math.toDegrees(latitudeResult) + ", longitude: " + Math.toDegrees(longitudeResult));
}
need to add bearing
For anyone looking, this is how I implemented this code in JavaScript:
function generatePoint(
latitude,
longitude,
distanceInMetres,
bearing = Math.floor(Math.random() * (360 - 1) + 1)
) {
const brngRad = deg2Rad(bearing);
const latRad = deg2Rad(latitude);
const lonRad = deg2Rad(longitude);
const EARTH_RADIUS_IN_METRES = 6371000;
const distFrac = distanceInMetres / EARTH_RADIUS_IN_METRES;
const latitudeResult = Math.asin(
Math.sin(latRad) * Math.cos(distFrac) +
Math.cos(latRad) * Math.sin(distFrac) * Math.cos(brngRad)
);
const a = Math.atan2(
Math.sin(brngRad) * Math.sin(distFrac) * Math.cos(latRad),
Math.cos(distFrac) - Math.sin(latRad) * Math.sin(latitudeResult)
);
const longitudeResult =
((lonRad + a + 3 * Math.PI) % (2 * Math.PI)) - Math.PI;
return {
latitude: rad2Deg(latitudeResult),
longitude: rad2Deg(longitudeResult),
bearing,
};
}
function deg2Rad(deg) {
return deg * (Math.PI / 180);
}
function rad2Deg(rad) {
return rad * (180 / Math.PI);
}
It will also generate a random bearing if none is provided

Android sqlite how to calculate distance from latitude and longitude [duplicate]

I'm not really good with mathematics but I need to calculate the distance of two different locations of the markers. Something like this:
public double CalculationByDistance(double initialLat, double initialLong, double finalLat, double finalLong){
return distance;
}
Or is there any alternative ways that I can calculate the distance of two markers, also I tried to google for answers.. but couldn't find any.
Reference:
http://en.wikipedia.org/wiki/Haversine_formula
Comments are appreciated :) Thanks!!
Try this, much simpler than Haversine!
Location me = new Location("");
Location dest = new Location("");
me.setLatitude(myLat);
me.setLongitude(myLong);
dest.setLatitude(destLat);
dest.setLongitude(destLong);
float dist = me.distanceTo(dest);
If you want to stick with Haversine, something like this:
public double CalculationByDistance(double initialLat, double initialLong,
double finalLat, double finalLong){
int R = 6371; // km (Earth radius)
double dLat = toRadians(finalLat-initialLat);
double dLon = toRadians(finalLong-initialLong);
initialLat = toRadians(initialLat);
finalLat = toRadians(finalLat);
double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(initialLat) * Math.cos(finalLat);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return R * c;
}
public double toRadians(double deg) {
return deg * (Math.PI/180);
}
Also, you need to create a method toRadians() that convert values from degrees to radians, which is quite easy.
Hope it helps!
From your wikipedia link, applying the formula directly you can do the following:
public double CalculationByDistance(double initialLat, double initialLong, double finalLat, double finalLong){
/*PRE: All the input values are in radians!*/
double latDiff = finalLat - initialLat;
double longDiff = finalLong - initialLong;
double earthRadius = 6371; //In Km if you want the distance in km
double distance = 2*earthRadius*Math.asin(Math.sqrt(Math.pow(Math.sin(latDiff/2.0),2)+Math.cos(initialLat)*Math.cos(finalLat)*Math.pow(Math.sin(longDiff/2),2)));
return distance;
}
Use the below method for calculating the distance of two different locations.
public double getKilometers(double lat1, double long1, double lat2, double long2) {
double PI_RAD = Math.PI / 180.0;
double phi1 = lat1 * PI_RAD;
double phi2 = lat2 * PI_RAD;
double lam1 = long1 * PI_RAD;
double lam2 = long2 * PI_RAD;
return 6371.01 * acos(sin(phi1) * sin(phi2) + cos(phi1) * cos(phi2) * cos(lam2 - lam1));
}
try this
/**
* This is the implementation Haversine Distance Algorithm between two places
* #author ananth
* R = earth’s radius (mean radius = 6,371km)
Δlat = lat2− lat1
Δlong = long2− long1
a = sin²(Δlat/2) + cos(lat1).cos(lat2).sin²(Δlong/2)
c = 2.atan2(√a, √(1−a))
d = R.c
*
*/
public class HaversineDistance {
/**
* #param args
* arg 1- latitude 1
* arg 2 — latitude 2
* arg 3 — longitude 1
* arg 4 — longitude 2
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
final int R = 6371; // Radious of the earth
Double lat1 = Double.parseDouble(args[0]);
Double lon1 = Double.parseDouble(args[1]);
Double lat2 = Double.parseDouble(args[2]);
Double lon2 = Double.parseDouble(args[3]);
Double latDistance = toRad(lat2-lat1);
Double lonDistance = toRad(lon2-lon1);
Double a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2) +
Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) *
Math.sin(lonDistance / 2) * Math.sin(lonDistance / 2);
Double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
Double distance = R * c;
System.out.println(“The distance between two lat and long is::” + distance);
}
private static Double toRad(Double value) {
return value * Math.PI / 180;
}
}

Calculate distance in miles only between two latitude and longitude

I have some confusion about calculation distance in miles. Whenever i am going to calculate in online it giving different result rather than i am using the below methods.
I need the distance in only miles. What the correction required in the below methods.
public double calculationByDistance(Location loc1, Location loc2) {
int Radius = 6371;// radius of earth in Km
double lat1 = loc1.getLatitude();
double lat2 = loc2.getLatitude();
double lon1 = loc1.getLongitude();
double lon2 = loc2.getLongitude();
double dLat = Math.toRadians(lat2 - lat1);
double dLon = Math.toRadians(lon2 - lon1);
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
+ Math.cos(Math.toRadians(lat1))
* Math.cos(Math.toRadians(lat2)) * Math.sin(dLon / 2)
* Math.sin(dLon / 2);
double c = 2 * Math.asin(Math.sqrt(a));
double valueResult = Radius * c;
double km = valueResult / 1;
km = km * 0.62137;
DecimalFormat newFormat = new DecimalFormat("####");
int kmInDec = Integer.valueOf(newFormat.format(km));
double meter = valueResult % 1000;
int meterInDec = Integer.valueOf(newFormat.format(meter));
Log.e("Radius Value", "" + valueResult + " KM " + kmInDec
+ " Meter " + meterInDec);
return Radius * c;
}
If anyone have idea please reply.
Thanks in advance...

Math.ceil not rounding the value

double totalInches = d * 0.3937;
double feetPart = totalInches / 12;
int inchesPart = (int) Math.ceil(totalInches - (feetPart * 12));
return (feetPart) + "' " + inchesPart + "''";
I am getting a value 6.9999999 ' 0". I am returning a string, is it the reason why the decimals values in feet is not getting rounded off.
I tried without casting too. double inchesPart = Math.ceil(totalInches - (feetPart * 12));, but still i get the same result.
Surely you need:
int feetPart = (int)Math.floor(totalInches / 12);
or just:
int feetPart = (int)(totalInches / 12);
To get the two parts you can use
int totalInches = (int) (d * 0.3937);
int feetPart = totalInches / 12;
int feetInchPart = totalInches % 12;

Apache POI rate formula inconsistency with long periods

In order to emulate Excel's rate function, I'm using the Apache POI rate function I grabbed from the svn:
private double calculateRate(double nper, double pmt, double pv, double fv, double type, double guess) {
//FROM MS http://office.microsoft.com/en-us/excel-help/rate-HP005209232.aspx
int FINANCIAL_MAX_ITERATIONS = 20; //Bet accuracy with 128
double FINANCIAL_PRECISION = 0.0000001; //1.0e-8
double y, y0, y1, x0, x1 = 0, f = 0, i = 0;
double rate = guess;
if (Math.abs(rate) < FINANCIAL_PRECISION) {
y = pv * (1 + nper * rate) + pmt * (1 + rate * type) * nper + fv;
}
else {
f = Math.exp(nper * Math.log(1 + rate));
y = pv * f + pmt * (1 / rate + type) * (f - 1) + fv;
}
y0 = pv + pmt * nper + fv;
y1 = pv * f + pmt * (1 / rate + type) * (f - 1) + fv;
// Find root by the Newton secant method
i = x0 = 0.0;
x1 = rate;
while ((Math.abs(y0 - y1) > FINANCIAL_PRECISION) && (i < FINANCIAL_MAX_ITERATIONS)) {
rate = (y1 * x0 - y0 * x1) / (y1 - y0);
x0 = x1;
x1 = rate;
if (Math.abs(rate) < FINANCIAL_PRECISION) {
y = pv * (1 + nper * rate) + pmt * (1 + rate * type) * nper + fv;
}
else {
f = Math.exp(nper * Math.log(1 + rate));
y = pv * f + pmt * (1 / rate + type) * (f - 1) + fv;
}
y0 = y1;
y1 = y;
++i;
}
return rate;
}
For calculateRate(120, 28.1, -2400, 0, 0, 0.1)), the output is the same as Excel: 0.599
But if I try the same calculation, this time with the values:
calculateRate(360, 15.9, -2400, 0, 0, 0.1))
In Excel I get 0.580, and the program returns -1.1500428517726355. Any hints?
There are a bunch of things that are wrong with this code that you have pasted in your question.
It assumes that a rate is always found (not true) and makes no provision for instances when a rate is not found.
Some of the statements will throw an error which could have been avoided by using a more appropriate programming statement. For instance, take the following statement from your code:
f = Math.exp(nper * Math.log(1 + rate));
This will throw an error when attempting to find Log of a negative or zero value. It could have been rewritten as
f = Math.pow(1 + rate, nper);
The comment in iterative calculations states that it is programming the secant method, yet the iterative calculations are checked for convergence of the wrong variable. It is testing for convergence of a future value when it should be testing for convergence of the interest rate.
I copy pasted your code in Notepad and removed the variable declaration of Java and replaced these with JavaScript variable declarations to test the code with your sample data. And just as I said, the code stops at the second iteration since the difference of future values goes out of error bound and since there is no test in place to see whether a rate is found, the code returns the interest rate as is and one which is wrong.
I am not sure why this code works in instances where it does report a correct rate as is the case with first data set. I would suggest re-coding of the function in a correct manner.
public double rate(double nper, double pmt, double pv)
{
//System.out.println("function rate : " + nper + " " + pmt + " pv " + pv);
double error = 0.0000001;
double high = 1.00;
double low = 0.00;
double rate = (2.0 * (nper * pmt - pv)) / (pv * nper);
while(true) {
// Check for error margin
double calc = Math.pow(1 + rate, nper);
calc = (rate * calc) / (calc - 1.0);
calc -= pmt / pv;
if (calc > error) {
// Guess is too high, lower the guess
high = rate;
rate = (high + low) / 2;
}
else if (calc < -error) {
// Guess is too low, higher the guess.
low = rate;
rate = (high + low) / 2;
}
else {
// Acceptable guess
break;
}
}
//System.out.println("Rate : " + rate);
return rate;
}
Example: =RATE(60, 2112500, 65000000) returns 0.025198; the same with Excel (correct).

Categories