Math.abs() Limit the amount of deimals - javascript

I have scoured the internet and I haven't found a solution that really works for me, yet.
var tv = Length * Type;
if (tv < 0)
{
cForm.voltage.value = "-" + Math.abs(tv) + " V";
}
else...
Some of the calculations with these two numbers come out to about the 15th decimal for some reason. I would like to limit the decimal amount that is returned, and NOT allow the number to round up or down. On a calculator it only comes out to about the third decimal, but Math.abs() brings it too far out.
.toFixed() Doesn't work for me because if the number only has 2 decimals it will add additional zeros at the end. I only want to display up to the fourth if it is calculated.

Just expanding on #goto-0 s comment, with the correct # of decimal places.
var tv = Length * Type;
if (tv < 0)
{
cForm.voltage.value = "-" + (Math.round(Math.abs(tv) * 10000) / 10000) + " V";
}
else...

Here's the implementation as a function that truncates the extra decimal places. If you want to round the output you could just use Number.toPrecision().
function toFixedDecimals(num, maxDecimals) {
var multiplier = Math.pow(10, maxDecimals);
return Math.floor(num * multiplier) / multiplier
}
console.log(toFixedDecimals(0.123456789, 4));
console.log(toFixedDecimals(100, 4));
console.log(toFixedDecimals(100.12, 4));

I'm sure its not the most efficient approach but it is pretty brainless -
grab your result
split it into an array based on the decimal point
then trim the decimal part to two digits (or however many you would like).
concat the pieces back together
Sorry for the long variable names - just trying to make it clear what was happening : )
// your starting number - can be whatever you'd like
var number = 145.3928523;
// convert number to string
var number_in_string_form = String(number);
// split the number in an array based on the decimal point
var result = number_in_string_form.split(".");
// this is just to show you what values you end up where in the array
var digit = result[0];
var decimal = result[1];
// trim the decimal lenght to whatever you would like
// starting at the index 0 , take the next 2 characters
decimal = decimal.substr(0, 2);
// concat the digit with the decimal - dont forget the decimal point!
var finished_value = Number(digit + "." + decimal);
In this case the finished_value would = 145.39

Related

How to retain the first 2 numbers as is after the decimal point. Javascript [duplicate]

This question already has answers here:
Truncate (not round off) decimal numbers in javascript
(32 answers)
Closed 1 year ago.
I would like to format my numbers to always display 2 decimal places. lets say: I have a number => 21.268998 , the o/p I'm looking is to chop the rest of the decimal point and keep only the first 2 i.e:
21.26
however with the tofixed or toPrecision approach to always rounds to a certain decimal which is causing issues when a number is 99.999999, it rounds to 100.000 which is not right.
var num1 = "1";
document.getElementById('num1').innerHTML = (Math.round(num1 * 100) / 100).toFixed(2); // this is showing correctly
var num2 = "99.99999";
document.getElementById('num2').innerHTML = (Math.round(num2 * 100) / 100).toFixed(2);// this is incorrect=> I want to show 99.99
any idea how to get the first numbers to show always without rounding them off to the next number.
Jsfiidle:
https://jsfiddle.net/8ohvyczg/1/
You can use slice method in javascript:
var num2 = 99.99999;
num2 = num2.slice(0, (num2.indexOf("."))+3);
document.getElementById('num2').innerHTML = num2;
Did u tried Math.trunc()?
var num = "99.99999";
var round=(Math.round(num * 100) / 100).toFixed(2)
var trunc=(Math.trunc(num * 100) / 100)
console.log(round);
console.log(trunc);
Here's an approach of a simple truncate, and not round off:
var number = 26.4363
var str = number.toString();
console.log(str.substring(0, str.indexOf(".")+3));
Many ways to do that. But you can write a custom function to do that. I use split and substring.
const num = "99.91999";
function parseNumber(num)
{
arr = num.split('.');
return arr[0] + '.' + arr[1].substring(0,2);
}
console.log(parseNumber(num))

Javascript decimal number comparison

I have two decimal numbers which only slightly differ at the last two decimal places
eg. num1 = 1.12345 and num2 = 1.1234567
but doing a num1 === num2 check fails.
What would be the best way in javascript to make the comparison return true if there are only few extra decimal places in num2 compared to num1?
I know that num2 could be rounded by few decimal problems but therein arises the problem because I don't know in advance how many decimal places would be truncated in num1.
There are two possible ways of doing this (that I am aware of). The first would be to use toFixed, to round your numbers. The second would be to present some precision factor, in order to define "slightly" (let's say slightly means "a difference less than 0.0001"). The functions that implement this are below
// a, b - the numbers you wish to compare, digits - the number of digits to round to
function compareUpTo(a, b, digits){
a.toFixed(digits) === b.toFixed(digits) // first we round the numbers, then we compare them
}
// a, b - the numbers you wish to compare, precision- the amount to which the numbers are allowed to be different (let's say 0.01 for up to two digits)
function compareUpTo2(a, b, precision){
Math.abs(a-b) < precision // we make the difference and check whether or not the difference is smaller than our desired precision (we use Math.abs to turn a negative difference into a positive one)
}
Your definition of === is not what === means, but I think I get what you are trying to do.
First, figure out which number is the shortest.
Then, only compare the numbers by the amount of decimals in the shorter number.
I'm sure there is a cleaner way to do this, but I've drawn it out step-by-step to show the progression and to help make sense of the process.
function compare(x, y){
// Convert both numbers to strings:
var str1 = x.toString();
var str2 = y.toString();
// Get the shortest string
var shortest = str1.length >= str2.length ? str2 : str1;
console.log("Shorter number is: " + shortest); // Just for testing
// Get number of decimals in shorter string
var dec = shortest.indexOf(".");
var numDecimals = shortest.length - dec - 1;
// Only compare up to the least amount of decimals
console.log(x + " and " + y + " equal? " + (str1.substr(0, numDecimals + dec + 1) === str2.substr(0, numDecimals + dec + 1)));
}
compare(1.12345, 1.1234567);
compare(1.22345, 1.1234567);
compare(-101.22345, -101.1234567);
compare(-101.12345, -101.1234567);
You can use toString and compare strings. This will solve the problem of not knowing in advance the number of digits.
num1 = 1.12345 ;
num2 = 1.1234567 ;
str1 = num1.toString();
str2= num2.toString();
leng1 =str1.length;
leng2=str2.length;
minLength = Math.min(leng1 ,leng2);//ignore extra decimals
str1 =str1.slice(0,minLength);
str2 =str2.slice(0,minLength);
console.log(str1 ===str2); //true
The way I would do this is to find the length of the "shorter" number, then truncate the "longer" number with this code from MDN:
function truncate(number, precision) {
var factor = Math.pow(10, precision);
// *shouldn't* introduce rounding errors
return Math.floor(number * factor) / factor;
}
Where precision is the length of the shorter number. Which, you could get like this:
let num1 = 1.12345,
num2 = 1.1234567;
// gets everything after the . as a string
let str1 = String.prototype.split.call(num1,'.')[1],
str2 = String.prototype.split.call(num2,'.')[1];
let precision = Math.min(str1.length, str2.length);
Then, call the above function on both numbers and do your comparison.
if(truncate(num1,precision) == truncate(num2,precision) //do stuff
I modified the function on the Math.round() page from MDN for this answer.

toFixed method without rounding to five digit

I have a number var x = 2.305185185185195;
x = x.toFixed(5);
x = 2.30519 but I require this without rounding i.e. 2.30518
I read some thread with two decimal places but could not find for five decimal places.
Any help would be appreciated.
You can use an apropriate factor and floor it and return the result of the division.
Basically this solution moves the point to the left with a factor of 10^d and gets an integer of that and divided the value with the former factor to get the right digits.
function getFlooredFixed(v, d) {
return (Math.floor(v * Math.pow(10, d)) / Math.pow(10, d)).toFixed(d);
}
var x = 2.305185185185195;
document.write(getFlooredFixed(x, 5));
If you need only a "part" of a number with a floating point without rounding, you can just "cut" it:
function cutNumber(number, digitsAfterDot) {
const str = `${number}`;
return str.slice(0, str.indexOf('.') + digitsAfterDot + 1);
}
const x = 2.305185185185195;
console.log(cutNumber(x, 5)); // 2.30518
This method is fast (https://jsfiddle.net/93m8akzo/1/) and its execution time doesn't depend on number or digitsAfterDot values.
You can also "play around" with both functions in a given fiddle for a better understanding of what they do.
You can read more about slice() method here - MDN documentation
NOTE This function is only an example, don't use it in production applications.
You should definitely add input values validation and errors handling!
The Math.trunc() function returns the integer part of a number by
removing any fractional digits
So you can multiply the number by 10^n where n is the desired number of precision, truncate the decimal part using Math.trunc(), divide by the same number (10^n) and apply toFixed() to format it (in order to get the form of 2.30 instead of 2.3 for example)
var x = 2.305185185185195;
console.log((Math.trunc(x*100000)/100000).toFixed(5));
I have sorted it out by adding a small amount if the decimal is 5, then rounding as usual:
function(value, decimals) {
var decimals = decimals || 2;
if( isNaN(value) ){ return 0; }
var decimalPart = value.toString().trim().split('.').pop(),
extra = decimalPart.substr(decimals, decimalPart.length - decimals);
if( extra == '5' &&
decimalPart.length > decimals
){
value = parseFloat(value) + (1 / ( Math.pow(10, decimals + 5) ) );
}
return Number( parseFloat( value ).toFixed( decimals ) );
}

How to get numbers with precision without round up or round down [duplicate]

This question already has answers here:
Truncate (not round off) decimal numbers in javascript
(32 answers)
Closed 8 years ago.
Im trying to get a number with precision to 2 decimals, for example this is what I want, if I have the numbers:
3.456 it must returns me 3.45
3.467 = 3.46
3.435 = 3.43
3.422 = 3.42
I don't want to round up or down or whatever just to get the numbers I see 2 places after .
Thanks
Okay, here is the answer
var a = 5.469923;
var truncated = Math.floor(a * 100) / 100; // = 5.46
Thanks everyone for helping.
Assuming Positive Numbers:
The code:
function roundDown(num,dec) {
return Math.floor(num*Math.pow(10,dec))/Math.pow(10,dec);
}
The test:
function test(num, expected) {
var val = roundDown(num,2);
var pass = val === expected;
var result = pass ? "PASS" : "FAIL";
var color = pass ? "GREEN" : "RED";
console.log("%c" + result + " : " + num + " : " + val, "background-color:" + color);
}
test(3.456, 3.45);
test(3.467, 3.46);
test(3.435, 3.43);
test(3.422, 3.42);
Basic idea:
Take number
Multiply the number to move decimal place to number of significant figures you want
Floor the number to remove the trailing numbers
Divide number back to get the correct value
If you want to have a trailing zero, you need to use toFixed(2) which will turn the number to a string.
function roundDown(num,dec) {
return Math.floor(num*Math.pow(10,dec))/Math.pow(10,dec).toFixed(2);
}
and the test cases would need to change to
test(3.456, "3.45");
test(3.467, "3.46");
test(3.435, "3.43");
test(3.422, "3.42");
Another option is a regular expression.
function roundDown(num,dec) {
var x = num.toString().match(/(\d*(\.\d{2}))?/);
return x ? parseFloat(x[0]) : "";
//return x ? parseFloat(x[0]).toFixed(2) : "";
}
Use String operation to achieve it.
var n = 4.56789;
var numbers = n.toString().split('.');
result = Number(numbers[0]+"."+numbers[1].substr(0,2));
alert(result);
Fiddle
You are looking at the number as if it were a string of digits, rather than a single value, so treat it like a string.-
function cutoff(n, cut){
var parts= String(n).split('.'), dec= parts[1];
if(!cut) return parts[0];
if(dec && dec.length>cut) parts[1]= dec.substring(0, cut);
return parts.join('.');
}
var n= 36.938;
cutoff(n,2)
/* returned value: (String)
36.93
*/
If you want a number, +cutoff(n,2) will do.
function truncateDec(num, decplaces) {
return (num*Math.pow(10,decplaces) - num*Math.pow(10,decplaces) % 1)/Math.pow(10,decplaces);
}
alert(truncateDec(105.678, 2)); // Returns 105.67
alert(truncateDec(105.678, 1)); // Returns 105.6
This could be simplified further if you do not require a dynamic number of decimal places
function truncateDec(num) {
return (num*100 - num*100 % 1)/100;
}
alert(truncateDec(105.678)); // Returns 105.67
How does it work?
The concept is that the main truncation works by getting the remainder from dividing the original decimal by 1. The remainder will be whatever is in the decimals places. The remainder operator is %
105.678 % 1 = 0.678
By subtracting this remainder from the original number, we will be left with only the integer.
105.678 - 0.678 = 105
To include x number of decimal places, we need to first multiply the original number by 10 to the power of that number of decimal places, thereby shifting the decimal backward by x positions. In this example, we will take x = 2.
105.678 * 10^2
= 105.678 * 100
= 10567.8
Now, we repeat the same procedure by subtracting the remainder again.
10567.8 % 1 = 0.8
10567.8 - 0.8 = 10567
And to return back to the number of places as requested, we divide it back by 10^x
10567 / 10^2
= 10567 / 100
= 105.67
Hope it helps!

Can I move a decimal in javascript without math?

I would love to be able to move a decimal point 2 places across an unknown amount of numbers without using math. I know that seems weird, but finite precision causes some shifts. My javascript is not strong, but I'd really like to learn how to chop up a number and do this if it's possible. So, I'm hoping you awesome folks can help.
The problem:
575/960 = 0.5989583333333334 using the console
I would like to make that a copy and pastable percentage like: 59.89583333333334%
If I use math and multiply by 100, it returns 59.895833333333336 because of finite precision
Is there a way to make that a string and just always move the decimal 2 places to the right to skip the math?
Here's a fiddle too, with the codes: http://jsfiddle.net/dandenney/W9fXz/
If you want to know why I need it and want the precision, it's for this little tool that I made for getting responsive percentages without using the calculator: http://responsv.com/flexible-math
If the original number is of this type of known structure and always has at least two digits to the right of the decimal, you can do it like this:
function makePercentStr(num) {
var numStr = num + "";
// if no decimal point, add .00 on end
if (numStr.indexOf(".") == -1) {
numStr += ".00";
} else {
// make sure there's at least two chars after decimal point
while (!numStr.match(/\.../)) {
numStr += "0";
}
}
return(numStr.replace(/\.(..)/, "$1.")
.replace(/^0+/, "") // trim leading zeroes
.replace(/\.$/, "") // trim trailing decimals
.replace(/^$/, "0") // if empty, add back a single 0
+ "%");
}
Working demo with test cases: http://jsfiddle.net/jfriend00/ZRNuw/
The question asks to solve the problem without Math but the below solution involves math. I am leaving it for just a reference
function convertToPercentage(num) {
//Changes the answer to string for checking
//the number of decimal places.
var numString = num + '';
var length = (numString).substring(numString.indexOf(".")+1).length;
//if the original decimal places is less then
//no need to display decimals as we are multiplying by 100
//else remove two decimals from the result
var precision = (length < 2 ? 0 : length-2);
//if the number never contained a decimal.
//Don't display decimal.
if(numString.indexOf(".") === -1) {
precision = 0;
}
return (num * 100).toFixed(precision) + "%";
}
Working jsFiddle here with same test cases as the accepted answer.
I've used this method because of the risk of floating errors:
const DECIMAL_SEP = '.';
function toPercent(num) {
const [integer, decimal] = String(num).split(DECIMAL_SEP);
// no decimal, just multiply by 100
if(typeof decimal === 'undefined') {
return num * 100;
}
const length = decimal.length;
if(length === 1) {
return Number(integer + decimal + '0');
}
if(length === 2) {
return Number(integer + decimal);
}
// more than 2 decimals, we shift the decimal separator by 2
return Number(integer + decimal.substr(0, 2) + DECIMAL_SEP + decimal.substr(2));
}
console.log(toPercent(10));
console.log(toPercent(1));
console.log(toPercent(0));
console.log(toPercent(0.01));
console.log(toPercent(0.1));
console.log(toPercent(0.12));
console.log(toPercent(0.123));
console.log(toPercent(12.3456));

Categories

Resources