Ok so after much searching I was unable to find anything that would tell me how to truncate a number to a specified number of significant digits without rounding so I had to invent my own so after a lot of tinkering and trying out a bunch of different things I think I’ve come up with a solution that should work correctly, so for the benefit of anyone else that might be looking to truncate a number to a given number of significant digits without rounding here is my solution.
Code: Select all
function truncateDecimals(number, significant_digits)
{
var string = String(number);
var decimal_position = string.indexOf('.');
if(number > 0 && decimal_position > 0
|| number < 0 && decimal_position == -1
|| number < 0 && decimal_position - 1 == significant_digits)
{
var string_length = significant_digits + 1;
}
if(number < 0 && decimal_position > 0 && decimal_position - 1 < significant_digits)
{
var string_length = significant_digits + 2;
}
if(number > 0 && decimal_position == -1
|| number > 0 && decimal_position == significant_digits)
{
var string_length = significant_digits;
}
if(decimal_position == -1)
{
var pad_zeros = "0".repeat(significant_digits - string.replace("-","").length);
var result = string + "." + pad_zeros;
}
else if(decimal_position > 0 && string.length < string_length)
{
var pad_zeros = "0".repeat(string_length - string.length);
var result = string + pad_zeros;
}
else
{
var result = string.substring(0, string_length);
}
return result;
}
to see a quick demo of this in action, just copy the code below to a new text document and then rename it from .txt to .html then open it up in your browser, and then hover where it says icon.
if you don't see the file extension then you will need to unchecked hide extensions for known file types.
Code: Select all
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>demo</title>
<style>
table#demo
{
margin:0;
padding:0;
border-collapse: collapse;
font-family: Arial;
margin-top:16px;
display:block
}
table#demo tr td
{
padding:0 2px;
}
table#demo tr td:nth-of-type(1)
{
text-align: center;
}
table#demo tr td:nth-of-type(2)
{
transform: translate(0px, -2px);
}
table#demo tr td:nth-of-type(3)
{
text-align: right;
}
table
{
display:inline-block;
vertical-align: top;
}
</style>
</head>
<body>
<table>
<tr data-name='icon1'>
<td>icon 1</td>
</tr>
<tr data-name='icon2'>
<td>icon 2</td>
</tr>
<tr data-name='icon3'>
<td>icon 3</td>
</tr>
<tr data-name='icon4'>
<td>icon 4</td>
</tr>
<tr data-name='icon5'>
<td>icon 5</td>
</tr>
<tr data-name='icon6'>
<td>icon 6</td>
</tr>
<tr data-name='icon7'>
<td>icon 7</td>
</tr>
<tr data-name='icon8'>
<td>icon 8</td>
</tr>
<tr data-name='icon9'>
<td>icon 9</td>
</tr>
<tr data-name='icon10'>
<td>icon 10</td>
</tr>
</table>
<table>
<tr data-name='icon11'>
<td>icon 11</td>
</tr>
<tr data-name='icon12'>
<td>icon 12</td>
</tr>
<tr data-name='icon13'>
<td>icon 13</td>
</tr>
<tr data-name='icon14'>
<td>icon 14</td>
</tr>
<tr data-name='icon15'>
<td>icon 15</td>
</tr>
<tr data-name='icon16'>
<td>icon 16</td>
</tr>
<tr data-name='icon17'>
<td>icon 17</td>
</tr>
<tr data-name='icon18'>
<td>icon 18</td>
</tr>
<tr data-name='icon19'>
<td>icon 19</td>
</tr>
<tr data-name='icon20'>
<td>icon 20</td>
</tr>
</table>
<table>
<tr data-name='icon21'>
<td>icon 21</td>
</tr>
<tr data-name='icon22'>
<td>icon 22</td>
</tr>
<tr data-name='icon23'>
<td>icon 23</td>
</tr>
<tr data-name='icon24'>
<td>icon 24</td>
</tr>
<tr data-name='icon25'>
<td>icon 25</td>
</tr>
<tr data-name='icon26'>
<td>icon 26</td>
</tr>
<tr data-name='icon27'>
<td>icon 27</td>
</tr>
</table>
<table id="demo">
<tr>
<td>X</td>
<td>:</td>
<td>0.00 km</td>
</tr>
<tr>
<td>Y</td>
<td>:</td>
<td>0.00 km</td>
</tr>
<tr>
<td>Z</td>
<td>:</td>
<td>0.00 km</td>
</tr>
</table>
<script>
var icons =
{
icon1: {x: -609840, y: 1879080, z: -1617000},
icon2: {x: 3552000, y: 333000, z: 4151400},
icon3: {x: 722400, y: -1187760, z: 1300320},
icon4: {x: -1603560, y: 506520, z: -1195320},
icon5: {x: -7022400, y: 435960, z: -1504440},
icon6: {x: 2009280, y: -1346520, z: 2655240},
icon7: {x: -5394600, y: -1110000, z: -3529800},
icon8: {x: -2348640, y: 1706040, z: 1743000},
icon9: {x: -3662400, y: 2055480, z: 1601040},
icon10: {x: -655200, y: -926520, z: -3623760},
icon11: {x: 5328000, y: -88800, z: 1931400},
icon12: {x: 3108000, y: 88800, z: -1776000},
icon13: {x: -1603560, y: -61320, z: -1195320},
icon14: {x: -1159200, y: 1637160, z: 22248240},
icon15: {x: -3071040, y: -493920, z: 3858960},
icon16: {x: -8783880, y: 192360, z: 3163440},
icon17: {x: -7970760, y: -1031520, z: -281400},
icon18: {x: -3981600, y: -1792560, z: -336840},
icon19: {x: -5961480, y: 990360 , z: -6830880},
icon20: {x: -2100000, y: -614880, z: -2161320},
icon21: {x: 3108000, y: 0, z: 3774000},
icon22: {x: -3928680, y: 451920, z: -1792560},
icon23: {x: -496440, y: -787920, z: -5553240},
icon24: {x: 0, y: 0, z: 10080000},
icon25: {x: 10080000, y: 0, z: 0},
icon26: {x: 0, y: 0, z: -10080000},
icon27: {x: -10080000, y: 0, z: 0},
};
var table = document.querySelector('table#demo');
function hoveron(event)
{
if(event.target.closest('table').id !== "demo")
{
var target = event.target.closest('tr').getAttribute('data-name');
var x_coordinate = icons[target]['x'] / 222 / 1000;
var y_coordinate = icons[target]['y'] / 222 / 1000;
var z_coordinate = icons[target]['z'] / 222 / 1000;
function truncateDecimals(number, significant_digits)
{
var string = String(number);
var decimal_position = string.indexOf('.');
if(number > 0 && decimal_position > 0
|| number < 0 && decimal_position == -1
|| number < 0 && decimal_position - 1 == significant_digits)
{
var string_length = significant_digits + 1;
}
if(number < 0 && decimal_position > 0 && decimal_position - 1 < significant_digits)
{
var string_length = significant_digits + 2;
}
if(number > 0 && decimal_position == -1
|| number > 0 && decimal_position == significant_digits)
{
var string_length = significant_digits;
}
if(decimal_position == -1)
{
var pad_zeros = "0".repeat(significant_digits - string.replace("-","").length);
var result = string + "." + pad_zeros;
}
else if(decimal_position > 0 && string.length < string_length)
{
var pad_zeros = "0".repeat(string_length - string.length);
var result = string + pad_zeros;
}
else
{
var result = string.substring(0, string_length);
}
return result;
}
if(x_coordinate < 1 && x_coordinate > -1)
{
table.rows[0].cells[2].innerHTML = Math.trunc(x_coordinate * 1000) + " m";
}
else
{
table.rows[0].cells[2].innerHTML = truncateDecimals(x_coordinate, 3) + " km";
}
if(y_coordinate < 1 && y_coordinate > -1)
{
table.rows[1].cells[2].innerHTML = Math.trunc(y_coordinate * 1000) + " m";
}
else
{
table.rows[1].cells[2].innerHTML = truncateDecimals(y_coordinate, 3) + " km";
}
if(z_coordinate < 1 && z_coordinate > -1)
{
table.rows[2].cells[2].innerHTML = Math.trunc(z_coordinate * 1000) + " m";
}
else
{
table.rows[2].cells[2].innerHTML = truncateDecimals(z_coordinate, 3) + " km";
}
}
}
var cells = document.querySelectorAll("td");
for (i = 0; i < cells.length; i++)
{
cells[i].addEventListener("mouseover", hoveron);
}
</script>
</body>
</html>
Now I’ll admit this isn’t the shortest or most elegant solution and sure it could probably be improved but so far as I can tell the logic is sound, it works correctly with both positive and negative numbers it also correctly pads the appropriate number of zeros regardless of whether it’s a whole number or a floating point number that is to short to meet the specified level of precision.
I tested this up to 10 significant digits and everything seemed to work fine.
EDIT: I refined the original function removing unnecessary code, I also fixed a minor oversight which cause the original function to do the wrong thing and thus give incorrect output.