Limit decimal places to specific situations (not round) - javascript

Im looking to limit a number do 2 decimal places, but only when the rest is zero. I dont want to round the numbers.
I tried using this example
(1.0000).toFixed(2)
the result would be 1.00, but if i have a number like (1.0030).toFixed(2), the result should be 1.003.
I tried using parseFloat with a combination of toFixed but doesn´t get the result i want.
Is there any function in javascript that does what im trying to achieve.

So you want a minimum of two decimals? Here's one way:
function toMinTwoDecimals(numString) {
var num = parseFloat(numString);
return num == num.toFixed(2) ? num.toFixed(2) : num.toString();
}
Examples:
toMinTwoDecimals("1.0030"); // returns "1.003"
toMinTwoDecimals("1.0000"); // returns "1.00"
toMinTwoDecimals("1"); // returns "1.00"
toMinTwoDecimals("-5.24342234"); // returns "-5.24342234"
In case you want to leave numbers with less than two decimals untouched, use this instead:
function toMinTwoDecimals(numString) {
var num = parseFloat(numString);
// Trim extra zeros for numbers with three or more
// significant decimals (e.g. "1.0030" => "1.003")
if (num != num.toFixed(2)) {
return num.toString();
}
// Leave numbers with zero or one decimal untouched
// (e.g. "5", "1.3")
if (numString === num.toFixed(0) || numString === num.toFixed(1)) {
return numString;
}
// Limit to two decimals for numbers with extra zeros
// (e.g. "1.0000" => "1.00", "1.1000000" => "1.10")
return num.toFixed(2);
}

Related

Truncate a number

function truncDigits(inputNumber, digits) {
const fact = 10 ** digits;
return Math.trunc(inputNumber * fact) / fact;
}
truncDigits(27624.399999999998,2) //27624.4 but I want 27624.39
I need to truncate a float value but don't wanna round it off. For example
27624.399999999998 // 27624.39 expected result
Also Math.trunc gives the integer part right but when you Math.trunc value 2762439.99 it does not give the integer part but gives the round off value i.e 2762434
Probably a naive way to do it:
function truncDigits(inputNumber, digits) {
return +inputNumber.toString().split('.').map((v,i) => i ? v.slice(0, digits) : v).join('.');
}
console.log(truncDigits(27624.399999999998,2))
At least it does what you asked though
Try this:
function truncDigits(inputNumber, digits){
return parseFloat((inputNumber).toFixed(digits));
}
truncDigits(27624.399999999998,2)
Your inputs are number (if you are using typescript). The method toFixed(n) truncates your number in a maximum of n digits after the decimal point and returns it as a string. Then you convert this with parseFloat and you have your number.
You can try to convert to a string and then use a RegExp to extract the required decimals
function truncDigits(inputNumber: number, digits: number) {
const match = inputNumber.toString().match(new RegExp(`^\\d+\\.[\\d]{0,${digits}}`))
if (!match) {
return inputNumber
}
return parseFloat(match[0])
}
Note: I'm using the string version of the RegExp ctor as the literal one doesn't allow for dynamic params.

What is the safest way to split a "Floating Point Number String" into its Whole and Fractional Parts

I have developed the following short function to split a number passed to it in a string format into its Whole and Fractional Parts (also outputted as strings).
Note1: The Whole part of the number can run into large numbers (in excess of 50 digits).
Note 2: The output result (the Whole and the Fraction strings) will not be converted into an integer or a float but will be further manipulated only as a string due to the Javascript rounding for large numbers. So going back to numbers is not a concern here
Because the function detects the machine's locale automatically, it is therefore expected that the user enters (passes) the number in the locale of his local machine or otherwise the number is generated programmatically and passed to the function.
The number is expected to be passed as a "string" due to the very large length and also because there is no handling for numbers passed in exponent (e) format.
The function uses the toLocaleString() to detect the decimal and thousand separators.
I have tested the function with the major number systems (.,' space) and so far, so good.
The question is, how safe will this code be, and are there any alternative better and safer methods to do it or corrections/changes necessary?
Thanks
function splitFloatString(NumString) {
var decimalSeparator = (1.1).toLocaleString().substring(1,2); // Get Decimal Separator
var thousandSeparator = (1000).toLocaleString().substring(1,2); // Get Thousands Separator
NumString += ""; // ensure a string
var fraction ="0"; // default no fractional part
NumString = NumString.replace(RegExp("\\"+thousandSeparator,"g"),""); //remove thousand separators if any
if (RegExp("\\"+decimalSeparator,"g").test(NumString)) { // test for decimal separator
var n = NumString.split(decimalSeparator); // Split at Decimal Seprator
NumString = n[0]; // The Whole part
if (n.length==2) fraction = n[1]; // The Fractional part
if (fraction=="") fraction ="0";
}
console.log("Whole: ("+NumString+"), Fraction: ("+fraction+")"); // added for testing
//return n=[NumString,fraction]; // normal return uncomment
}
//------------------------------------------------------------------------------------
// Tests assuming user's machine and user enters/passes US-EN separators as an example
//------------------------------------------------------------------------------------
splitFloatString("123456789123456699999887788812340786.45678907656912574321115194123123456789");
splitFloatString("1,234,567,891,234,566,999,998,888,812,340.456520754186789075194123123456789");
splitFloatString("200")
splitFloatString("0.")
splitFloatString(123456.2349999)
splitFloatString("")
splitFloatString()
According to me, you are just complicating the whole thing unnecessarily. Here's a simple way to achieve the same result.
function getLocaleSeparators() {
const testNumber = 1000.1.toLocaleString()
return [testNumber.substring(1,2), testNumber.substring(5,6)]
}
function splitFloatString(number) {
const numberString = number.toString()
const [thousandSeparator, decimalSeparator] = getLocaleSeparators()
let [wholePart, fractionPart] = numberString.replace(new RegExp(thousandSeparator, 'g'), '').split(decimalSeparator)
wholePart = wholePart || "0"
fractionPart = fractionPart || "0"
console.log(`Whole: ${wholePart}, Fraction: ${fractionPart}`);
}
function getLocaleSeparators() {
const testNumber = 1000.1.toLocaleString()
return [testNumber.substring(1,2), testNumber.substring(5,6)]
}
function splitFloatString(number) {
const numberString = number.toString()
const [thousandSeparator, decimalSeparator] = getLocaleSeparators()
let [wholePart, fractionPart] = numberString.replace(new RegExp(thousandSeparator, 'g'), '').split(decimalSeparator)
wholePart = wholePart || "0"
fractionPart = fractionPart || "0"
console.log(`Whole: ${wholePart}, Fraction: ${fractionPart}`);
}
splitFloatString("123456789123456699999887788812340786.45678907656912574321115194123123456789");
splitFloatString("1,234,567,891,234,566,999,998,888,812,340.456520754186789075194123123456789");
splitFloatString("200")
splitFloatString("0.")
splitFloatString(123456.2349999)
splitFloatString("")
I recommend you to use the math.floor function for such purposes.
It rounds the number passed as parameter to its nearest integer in downward direction:
Also, The Math.ceil() function rounds a number up to the next largest whole number or integer.
For other handy options, you can check out this https://www.w3docs.com/snippets/javascript/how-to-convert-a-float-number-to-whole-number-in-javascript.html
Please try with this one. might help you.
number = "21212.32323";
var numberString = number + ''; // converts into string
var index = numberString.lastIndexOf("."); // get the index
var strFloat, wholeStr;
if(index === -1) {
strFloat = '';
wholeStr = numberString.replace(/[^\w\s]/gi, '').replace(/ /g,'')
} else {
strFloat = numberString.substring(index + 1); // get the decimal part
var strWhole = numberString.substring(0, index); // get the number
wholeStr = strWhole.replace(/[^\w\s]/gi, '').replace(/ /g,'') // remove spcl character
}
console.log(`Whole: ${wholeStr}, Fraction: ${strFloat}`);
And yes you can not exceed MAX_SAFE_INTEGER in javascript i.e 32-bits.
What is JavaScript's highest integer value that a number can go to without losing precision?
Have been able to finally get the final answer I was looking for.
Thanks to all for their assistance and ideas:
function numberSplit (NumString) {
var decimalSep = 1.1.toLocaleString().substring(1,2), // Get Deciaml Separator
thousandSep = 1e3.toLocaleString().substring(1,2), // Get Thousand Separator
fraction = "0", // Default "0"
n = (NumString = (NumString +="").replace(RegExp("\\"+thousandSep,"g"),"")).split(decimalSep);
NumString = n[0] ; // Get Whole Part
NumString == "" && (NumString = undefined); // Whole = undefined if empty
n.length == 2 && (fraction = n[1]); // Get Fractional part (only if 1 decimal place)
fraction == "" && (fraction = "0"); // Fraction = 0 if empty
console.log("Whole: ("+NumString+"), Fraction: ("+fraction+")")
}
//-----------------------------------------------------------
// Ttests assuming user enters US-EN separators as an example
//-----------------------------------------------------------
numberSplit("123456789123456699999887788812340786.45678907656912574321115194123123456789");
numberSplit("1,234,567,891,234,566,999,998,888,812,340.456520754186789075194123123456789");
numberSplit("200")
numberSplit("0.")
numberSplit(123456.2349999)
numberSplit("1.2.3"); // Fractional part ignored as invalid
numberSplit("") // Return undefined
numberSplit() // Return undefined
numberSplit(NaN) // Return NaN
numberSplit(undefined) // Return undefined

Counting numbers after decimal point in JavaScript

I have a problem in JavaScript. Is it possible to check how many numbers are after the decimal point? I tried to do it using a.toString().split(".")[1]), but if there is no decimal point in the number, there is an error. What should I do if I want the system to do nothing if there is no decimal point?
You're on the right track. You can also .includes('.') to test if it contains a decimal along with .length to return the length of the decimal portion.
function decimalCount (number) {
// Convert to String
const numberAsString = number.toString();
// String Contains Decimal
if (numberAsString.includes('.')) {
return numberAsString.split('.')[1].length;
}
// String Does Not Contain Decimal
return 0;
}
console.log(decimalCount(1.123456789)) // 9
console.log(decimalCount(123456789)) // 0
Convert to a string, split on “.”, then when there is no “.” to split on, assume it’s empty string '' (the part you’re missing), then get said string’s length:
function numDigitsAfterDecimal(x) {
var afterDecimalStr = x.toString().split('.')[1] || ''
return afterDecimalStr.length
}
console.log(numDigitsAfterDecimal(1.23456))
console.log(numDigitsAfterDecimal(0))
You could check if no dot is available, then return zero, otherwise return the delta of the lenght and index with an adjustment.
function getDigits(v) {
var s = v.toString(),
i = s.indexOf('.') + 1;
return i && s.length - i;
}
console.log(getDigits(0));
console.log(getDigits(0.002));
console.log(getDigits(7.654321));
console.log(getDigits(1234567890.654321));
The condition you need is:
number.split('.')[1].length
It checks if there are any numbers after the dot which separates the number from its decimal part.
I'm not sure if you are able to use split on numbers though. If not, parse it to a string.
You first need to convert the decimal number to string and then get the count of character after decimal point,
var a = 10.4578;
var str = a.toString();
if(str){
var val = str.split('.');
if(val && val.length == 2){
alert('Length of number after decimal point is ', val[1].length);
} else {
alert('Not a decimal number');
}
}
The output is 4

Adding Two Decimal Places using JavaScript

Good day Everyone!
I want to know how to return the output with two decimal places. Instead of 10,000 I want it to return 10,000.00. Also I already put .toFixed(2) but it's not working.
When the amount has decimal number other than zero, the values appear on the printout, but when the decimal number has a zero value, the Zeros won't appear on the printout.
Also, I have added a value of Wtax that was pulled-out on a "Bill Credit" Transaction.
Output:
Numeral.js - is a library that you can use for number formatting.
With that you can format your number as follows:
numeral(10000).format('$0,0.00');
Hope this will help you.
You can try this
var x = 1000; // Raw input
x.toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, '$1,') //returns you 1,000.00
Alternately you can use Netsuite's currency function too
nlapiFormatCurrency('1000'); // returns you 1,000.00
nlapiFormatCurrency('1000.98'); // returns you 1,000.98
You might consider below code. It can round off decimal values based on the decimal places.
This also addresses the issue when rounding off negative values by getting first the absolute value before rounding it off. Without doing that, you will have the following results which the 2nd sample is incorrect.
function roundDecimal(decimalNumber, decimalPlace)
{
//this is to make sure the rounding off is correct even if the decimal is equal to -0.995
var bIsNegative = false;
if (decimalNumber < 0)
{
decimalNumber = Math.abs(decimalNumber);
bIsNegative = true;
}
var fReturn = 0.00;
(decimalPlace == null || decimalPlace == '') ? 0 : decimalPlace;
var multiplierDivisor = Math.pow(10, decimalPlace);
fReturn = Math.round((parseFloat(decimalNumber) * multiplierDivisor).toFixed(decimalPlace)) / multiplierDivisor;
fReturn = (bIsNegative) ? (fReturn * -1) : fReturn;
fReturn = fReturn.toFixed(decimalPlace)
return fReturn;
}
Below are the test sample
And this test sample after addressing the issue for negative values.

Save integer as float

function prec(numb){
var numb_string = numb.toString().split('.')
return numb_string[(numb_string.length - 1)].length
}
function randy(minimum, maximum) {
var most_accurate = Math.max ( prec(minimum), prec(maximum) );
return ( ( Math.random() * ( maximum - minimum ) + minimum ).toFixed( most_accurate ) );
}
// returns random numbers between these points. 1 decimal place of precision:
console.log( randy(2.4,4.4) );
// returns random numbers between these points. 3 decimal places of precision:
console.log( randy(2.443,4.445) );
// returns random numbers between these points. Want 3 decimal places of precision. However, get 0:
console.log( randy(2.000,4.000) );
// Why do I get 0 decimal places? Because floats are rounded into integers automatically:
console.log( 4.0 ); // want 4.0 to be logged. Instead I get '4'
You don't need to read how the functions work. Just the console logs.
Basically, I need to return a random number between two points to a degree of precision. The precision is automatically derived from the most precise float passed to the randy function.
This works fine when the number range is 3.5 3.7 or 34.4322 800.3233 but not 2.0, 3.0 or 4.0000, 5.0000
Then the number is appears to be automatically saved as an integer:
console.log( 2.0 ) //=> 2
I want to extend the Number prototype so that 2.0 is saved as 2.0 so that this function can find the precision:
function prec(numb){
var numb_string = numb.toString().split('.')
return numb_string[(numb_string.length - 1)].length
}
It currently thinks that 3.000000000 has a precision of 0 decimal places because if 3E8 is passed in as the numb parameter, it's read as 3. I want it read as 3.000000000
While I can do this randy(2.toFixed(3),3.toFixed(3)) it gets unreadable and it would be undeniably nicer to do this for smaller precisions: randy(2.000,3.000).
Is this possible?
Fiddle
There is a clever way to solve this problem , is to define a class that helps you managing the number values and the decimal values.
function HappyNumber()
{
this.value = (typeof(arguments[0]) == "number") ? arguments[0] : 0;
this.decimal = (typeof(arguments[1]) == "number") ? arguments[1] : 0;
this.Val = function()
{
return parseFloat(this.value.toFixed(this.decimal));
}
this.toString = function()
{
return (this.value.toFixed(this.decimal)).toString();
}
}
How this class works
Now first thing to do is to create a new number like this
var Num = HappyNumber(4.123545,3);
// first argument is the value
// and second one is decimal
To get the value of your variable, you should use the function Val like this
console.log(Num.Val()); // this one prints 4.123 on your console
The most important part is this one, when you use the toString function it return your number
Num.toString() // it returns "4.123"
(new HappyNumber(4,4)).toString(); // it returns "4.0000"
Now you pass arguments as (HappyNumber), and inside your function use toString and it returns the right value you need and it works with numbers like 1.00 2.000 4.00000
This will do what you want. (Warning: This is probably not a good idea.)
Number.prototype.toString = function () { return this.toFixed(1); }

Categories

Resources