Scott Fell
asked on
Convert Units Of Distance (Miles, Meters, Kilometer), Rounding Issues
Not sure if it is the conversion formulas, rounding formula or just logic. But on the sample below, select "marathon" and I am using 42195 meters as seen in the html code. This gets converted to kilometers 42.197 which seems odd. then use then use the drop down to change from kilometers, to miles, to meters and back to kilometers and the number is not the same in the text box. It is now 42.199
http://jsbin.com/codowocore/edit?html,js,output
JQUERY
HTML
http://jsbin.com/codowocore/edit?html,js,output
JQUERY
$(function() {
// select length of run
var currentMeasure = $('select#distanceUnit option:selected').text(); // current distance unit (miles, meters)
$('#distanceSelect').on('change', function() { // get the distance from drop down
var distanceSelect = $('#distanceSelect').val();
var convertTo = $('select#distanceUnit option:selected').text(); // convert from meters or what is currently selected to new measure
if (distanceSelect !== '') {
// convert distance to selected distance unit
var c = convert('Meter', convertTo, distanceSelect);
// place converted lenght in text box
$('#distance').val(c);
}
});
// recalculate the distance measure if change unit of measure
$('#distanceUnit').on('change', function() {
var currentDistance = $('#distance').val();
var newMeasure = $(this).val();
var newDistance = convert(currentMeasure, newMeasure, currentDistance);
$('#distance').val(newDistance);
currentMeasure = newMeasure;
});
});
function convert(from, to, dist) {
var conv;
switch (from + to) {
// convert from meters
case 'MeterKilometer':
conv = dist * 0.001;
break;
case 'MeterMile':
conv = dist * 0.00062137119223733;
break;
case 'MeterMeter':
conv = dist * 1;
break;
// convert from miles
case 'MileKilometer':
conv = dist * 1.609344;
break;
case 'MileMile':
conv = dist * 1;
break;
case 'MileMeter':
conv = dist * 1609.344;
break;
// convert from kilometer
case 'KilometerKilometer':
conv = dist * 1;
break;
case 'KilometerMile':
conv = dist * 0.62137119223733;
break;
case 'KilometerMeter':
conv = dist * 1000;
break;
}
//alert(conv);
convr = Math.ceil(conv*1000)/1000;
return convr;
}
HTML
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<form>
<div class="form-group">
<label>Distance</label>
<select id="distanceSelect" name="distanceSelect">
<option value="">Custom</option>
<option value="42195">Marathon</option>
<option value="21097.5">Half-Marathon</option>
<option value="5000">5K</option>
<option value="10000">10K</option>
<option value="25000">25K</option>
<option value="30000">30K</option>
<option value="50000">50K</option>
<option value="80467.2">50M</option>
<option value="100000">100K</option>
<option value="160934">100M</option>
</select>
<input id="distance" type="text" name="distance" >
<select id="distanceUnit">
<option value="Kilometer">Kilometer</option>
<option value="Mile">Mile</option>
<option value="Meter">Meter</option>
</select>
</div>
</form>
</body>
</html>
Floating point arithmetic is what JavaScript uses. Considered accurate to 15 decimal places. Your calculation goes past that.
Do you need that level of accuracy?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
It's a JavaScript issue: http://www.w3schools.com/js/js_numbers.asp
You were almost there with the *1000/1000. As you can see in the reference, the suggestion is to do the factor of ten multiplication at the time of initial calculation. I.e. At each conversion line
You were almost there with the *1000/1000. As you can see in the reference, the suggestion is to do the factor of ten multiplication at the time of initial calculation. I.e. At each conversion line
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thank you! Both are answers I was looking for. I ended up with toFixed(3). However, d-glitch's solution is brilliant.
ASKER
I want to let you know if an update where I am using d-glitch's micron conversion and it works. However, the key is to not doing any rounding because that will of course mess things up especially going from miles to metric. The work around would be to store and calculate on a hidden variable and display something rounded. I am sticking with keeping the raw value. http://jsbin.com/codowocore/edit?html,js,output
$(function() {
// select length of run
var currentMeasure = $('select#distanceUnit option:selected').text(); // current distance unit (miles, meters)
$('#distanceSelect').on('change', function() { // get the distance from drop down
var distanceSelect = $('#distanceSelect').val();
var convertTo = $('select#distanceUnit option:selected').text(); // convert from meters or what is currently selected to new measure
if (distanceSelect !== '') {
// convert distance to selected distance unit
var c = convert('Meter', convertTo, distanceSelect);
// place converted lenght in text box
$('#distance').val(c);
}
});
// recalculate the distance measure if change unit of measure
$('#distanceUnit').on('change', function() {
var currentDistance = $('#distance').val();
var newMeasure = $(this).val();
var newDistance = convert(currentMeasure, newMeasure, currentDistance);
$('#distance').val(newDistance);
currentMeasure = newMeasure;
});
});
function convert(convertFrom, convertTo, dist) {
//alert(convertTo+convertFrom);
var conv;
switch (convertFrom + convertTo) {
// convert from meters
case 'MeterKilometer':
conv = dist * 1000000;
conv = conv / 1000000000;
break;
case 'MeterMile':
conv = dist * 1000000;
conv = conv / 1609344000;
break;
case 'MeterMeter':
conv = dist * 1;
break;
// convert from miles
case 'MileKilometer':
conv = dist * 1609344000;
conv = conv / 1000000000;
break;
case 'MileMile':
conv = dist * 1;
break;
case 'MileMeter':
conv = dist * 1609344000;
conv = conv / 1000000;
break;
// convert from kilometer
case 'KilometerKilometer':
conv = dist * 1;
break;
case 'KilometerMile':
conv = dist * 1000000000;
conv = conv / 1609344000;
break;
case 'KilometerMeter':
conv = dist * 1000000000;
conv = conv / 1000000;
break;
}
return conv;
}
ASKER
One other note, the conversion of microns and miles is off
1 mi = 16,093,440,000 u is what is listed and
it should be
1 mi = 1,609,344,000 u
1 mi = 16,093,440,000 u is what is listed and
it should be
1 mi = 1,609,344,000 u
>> the conversion of microns and miles is off [by a factor of 10]
Sorry about that. Java may good for 15 digits, but my HP-15C is only good for 9, so I was trying to keep track of the decimal point in my head.
Sorry about that. Java may good for 15 digits, but my HP-15C is only good for 9, so I was trying to keep track of the decimal point in my head.