I have a script which returns a price for a product. However, the price may or may not include trailing zeros, so sometimes I might have 258.22 and other times I might have 258.2. In the latter case, I need to add the trailing zero. How would I go about doing this?
You can use javascript's toFixed method (source), you don't need jQuery. Example:
var number = 258.2;
var rounded = number.toFixed(2); // rounded = 258.20
Edit: Electric Toolbox link has succumbed to linkrot and blocks the Wayback Machine so there is no working URL for the source.
Javascript has a function - toFixed - that should do what you want ... no JQuery needed.
var n = 258.2;
n.toFixed (2); // returns 258.20
I don't think jQuery itself has any string padding functions (which is what you're looking for). It's trivial to do, though:
function pad(value, width, padchar) {
while (value.length < width) {
value += padchar;
}
return value;
}
Edit The above is great for strings, but for your specific numeric situation, rosscj2533's answer is the better way to go.
Related
I am creating a program that needs to have a way of "doctoring" a numerical equation. It needs to be able to simplify to the numbers and the basic numerical equation, without extra parentheses and negative and positive signs. Example:
var input = '[doctor] 2+-(-(2))'
var doctorPositive = input.search('[doctor]')
if (doctorPositive > -1) {
var deleteDoc = input.replace('[doctor]', '')
// Code here
document.getElementById('output').innerHTML = doctored;
}
I need deleteDoc which is currently equal to;
'2+-(-(2))'
to become:
'2+2"
I need this to work for almost any numerical equation. It cannot change any variables within the equation however. I don't know where to start.
This looks a lot like homework.
This will work for the 1 input you provided and probably a few other simple strings:
'2+-(-(2))'.replaceAll('(', '').replaceAll(')', '').replaceAll('--', '+').replaceAll('++', '+')
We all know that +, Number() and parseInt() can convert string to integer.
But in my case I have very weird result.
I need to convert string '6145390195186705543' to number.
let str = '6145390195186705543';
let number = +str; // 6145390195186705000, but should be: 6145390195186705543
Could someone explain why and how to solve it?
Your number is above the Number.MAX_SAFE_INTEGER (9,007,199,254,740,991), meaning js might have a problem to represent it well.
More information
You are outside the maximum range. Check in your console by typing Number.MAX_SAFE_INTEGER
If you want a number outside this range, take a look into BigInt that allows to define numbers beyond the safe range
https://developers.google.com/web/updates/2018/05/bigint
Read the documentation well before using it since the usage is different than usual
I am guessing this is to solve the plusOne problem in leetcode. As others have answered, you cannot store value higher than the max safe integer. However you can write logic to add values manually.
If you want to add one to the number represented in the array, you can use the below function. If you need to add a different value, you need to tweak the solution a bit.
var plusOne = function(digits) {
let n = digits.length, carry=0;
if(digits[n-1]<9){
digits[n-1] +=1;
} else{
digits[n-1] = 0;
carry=1;
for(let i=n-2;i>=0;i--){
if(digits[i]<9){
digits[i]+=1;
carry=0;
break;
}else{
digits[i]=0;
}
}
if(carry>0){
digits.unshift(carry);
}
}
return digits;
};
Short answer: Your string represents a number to large to fit into the JavaScript number container.
According to the javascript documentation the maximum safe number is 2^53 which is 9007199254740992 source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number
When you try and convert your number you're creating an overflow exception so you get weird results.
This is an extension of this SO question
I made a function to see if i can correctly format any number. The answers below work on tools like https://regex101.com and https://regexr.com/, but not within my function(tried in node and browser):
const
const format = (num, regex) => String(num).replace(regex, '$1')
Basically given any whole number, it should not exceed 15 significant digits. Given any decimal, it should not exceed 2 decimal points.
so...
Now
format(0.12345678901234567890, /^\d{1,13}(\.\d{1,2}|\d{0,2})$/)
returns 0.123456789012345678 instead of 0.123456789012345
but
format(0.123456789012345,/^-?(\d*\.?\d{0,2}).*/)
returns number formatted to 2 deimal points as expected.
Let me try to explain what's going on.
For the given input 0.12345678901234567890 and the regex /^\d{1,13}(\.\d{1,2}|\d{0,2})$/, let's go step by step and see what's happening.
^\d{1,13} Does indeed match the start of the string 0
(\. Now you've opened a new group, and it does match .
\d{1,2} It does find the digits 1 and 2
|\d{0,2} So this part is skipped
) So this is the end of your capture group.
$ This indicates the end of the string, but it won't match, because you've still got 345678901234567890 remaining.
Javascript returns the whole string because the match failed in the end.
Let's try removing $ at the end, to become /^\d{1,13}(\.\d{1,2}|\d{0,2})/
You'd get back ".12345678901234567890". This generates a couple of questions.
Why did the preceding 0 get removed?
Because it was not part of your matching group, enclosed with ().
Why did we not get only two decimal places, i.e. .12?
Remember that you're doing a replace. Which means that by default, the original string will be kept in place, only the parts that match will get replaced. Since 345678901234567890 was not part of the match, it was left intact. The only part that matched was 0.12.
Answer to title question: your function doesn't replace, because there's nothing to replace - the regex doesn't match anything in the string. csb's answer explains that in all details.
But that's perhaps not the answer you really need.
Now, it seems like you have an XY problem. You ask why your call to .replace() doesn't work, but .replace() is definitely not a function you should use. Role of .replace() is replacing parts of string, while you actually want to create a different string. Moreover, in the comments you suggest that your formatting is not only for presenting data to user, but you also intend to use it in some further computation. You also mention cryptocurriencies.
Let's cope with these problems one-by-one.
What to do instead of replace?
Well, just produce the string you need instead of replacing something in the string you don't like. There are some edge cases. Instead of writing all-in-one regex, just handle them one-by-one.
The following code is definitely not best possible, but it's main aim is to be simple and show exactly what is going on.
function format(n) {
const max_significant_digits = 15;
const max_precision = 2;
let digits_before_decimal_point;
if (n < 0) {
// Don't count minus sign.
digits_before_decimal_point = n.toFixed(0).length - 1;
} else {
digits_before_decimal_point = n.toFixed(0).length;
}
if (digits_before_decimal_point > max_significant_digits) {
throw new Error('No good representation for this number');
}
const available_significant_digits_for_precision =
Math.max(0, max_significant_digits - digits_before_decimal_point);
const effective_max_precision =
Math.min(max_precision, available_significant_digits_for_precision);
const with_trailing_zeroes = n.toFixed(effective_max_precision);
// I want to keep the string and change just matching part,
// so here .replace() is a proper method to use.
const withouth_trailing_zeroes = with_trailing_zeroes.replace(/\.?0*$/, '');
return withouth_trailing_zeroes;
}
So, you got the number formatted the way you want. What now?
What can you use this string for?
Well, you can display it to the user. And that's mostly it. The value was rounded to (1) represent it in a different base and (2) fit in limited precision, so it's pretty much useless for any computation. And, BTW, why would you convert it to String in the first place, if what you want is a number?
Was the value you are trying to print ever useful in the first place?
Well, that's the most serious question here. Because, you know, floating point numbers are tricky. And they are absolutely abysmal for representing money. So, most likely the number you are trying to format is already a wrong number.
What to use instead?
Fixed-point arithmetic is the most obvious answer. Works most of the time. However, it's pretty tricky in JS, where number may slip into floating-point representation almost any time. So, it's better to use decimal arithmetic library. Optionally, switch to a language that has built-in bignums and decimals, like Python.
I am just dipping my toe into the confusing world of javascript, more out of necessity than desire and I have come across a problem of adding two integers.
1,700.00 + 500.00
returns 1,700.00500.00
So after some research I see that 1,700.00 is being treated as a string and that I need to convert it.
The most relevant pages I read to resolve this were this question and this page. However when I use
parseInt(string, radix)
it returns 1. Am I using the wrong function or the an incorrect radix (being honest I can't get my head around how I decide which radix to use).
var a="1,700.00";
var b=500.00;
parseInt(a, 10);
Basic Answer
The reason parseInt is not working is because of the comma. You could remove the comma using a regex such as:
var num = '1,700.00';
num = num.replace(/\,/g,'');
This will return a string with a number in it. Now you can parseInt. If you do not choose a radix it will default to 10 which was the correct value to use here.
num = parseInt(num);
Do this for each of your string numbers before adding them and everything should work.
More information
How the replace works:
More information on replace at mdn:
`/` - start
`\,` - escaped comma
`/` - end
`g` - search globally
The global search will look for all matches (it would stop after the first match without this)
'' replace the matched sections with an empty string, essentially deleting them.
Regular Expressions
A great tool to test regular expressions: Rubular and more info about them at mdn
If you are looking for a good tutorial here is one.
ParseInt and Rounding, parseFloat
parseInt always rounds to the nearest integer. If you need decimal places there are a couple of tricks you can use. Here is my favorite:
2 places: `num = parseInt(num * 100) / 100;`
3 places: `num = parseInt(num * 1000) / 1000;`
For more information on parseInt look at mdn.
parseFloat could also be used if you do not want rounding. I assumed you did as the title was convert to an integer. A good example of this was written by #fr0zenFry below. He pointed out that parseFloat also does not take a radix so it is always in base10. For more info see mdn.
Try using replace() to replace a , with nothing and then parseFloat() to get the number as float. From the variables in OP, it appears that there may be fractional numbers too, so, parseInt() may not work well in such cases(digits after decimal will be stripped off).
Use regex inside replace() to get rid of each appearance of ,.
var a = parseFloat('1,700.00'.replace(/,/g, ''));
var b = parseFloat('500.00'.replace(/,/g, ''));
var sum = a+b;
This should give you correct result even if your number is fractional like 1,700.55.
If I go by the title of your question, you need an integer. For this you can use parseInt(string, radix). It works without a radix but it is always a good idea to specify this because you never know how browsers may behave(for example, see comment #Royi Namir). This function will round off the string to nearest integer value.
var a = parseInt('1,700.00'.replace(/,/g, ''), 10); //radix 10 will return base10 value
var b = parseInt('500.00'.replace(/,/g, ''), 10);
var sum = a+b;
Note that a radix is not required in parseFloat(), it will always return a decimal/base10 value. Also, it will it will strip off any extra zeroes at the end after decimal point(ex: 17500.50 becomes 17500.5 and 17500.00 becomes 17500). If you need to get 2 decimal places always, append another function toFixed(decimal places).
var a = parseFloat('1,700.00'.replace(/,/g, ''));
var b = parseFloat('500.00'.replace(/,/g, ''));
var sum = (a+b).toFixed(2); //change argument in toFixed() as you need
// 2200.00
Another alternative to this was given by #EpiphanyMachine which will need you to multiply and then later divide every value by 100. This may become a problem if you want to change decimal places in future, you will have to change multiplication/division factor for every variable. With toFixed(), you just change the argument. But remember that toFixed() changes the number back to string unlike #EpiphanyMachine solution. So you will be your own judge.
try this :
parseFloat(a.replace(/,/g, ''));
it will work also on : 1,800,300.33
Example :
parseFloat('1,700,800.010'.replace(/,/g, '')) //1700800.01
Javascript doesn't understand that comma. Remove it like this:
a.replace(',', '')
Once you've gotten rid of the comma, the string should be parsed with no problem.
I need to compare a float value entered in a web form against a range. The problem is that the client computers may have various locale settings, meaning that user may use either "." or "," to separate the integer part from decimal one.
Is there a simple way to do it? As it is for an intranet and that they are only allowed to use IE, a VBScript is fine, even if I would prefer to use JavaScript.
EDIT: Let me clarify it a bit:
I cannot rely on the system locale, because, for example, a lot of our french customers use a computer with an english locale, even if they still use the comma to fill data in the web forms.
So I need a way to perform a check accross multiple locale "string to double" conversion.
I know that the raise condition is "what about numbers with 3 decimal digits", but in our environment, this kind of answer never happen, and if it happens, it will be threated as an out of range error due to the multiplication by a thousand, so it's not a real issue for us.
In Javascript use parseFloat on the text value to get a number. Similarly in VBScript use CDbl on the text value. Both should conform to the current locale settings enforce for the user.
This code should work:
function toFloat(localFloatStr)
var x = localFloatStr.split(/,|\./),
x2 = x[x.length-1],
x3 = x.join('').replace(new RegExp(x2+'$'),'.'+x2);
return parseFloat(x3);
// x2 is for clarity, could be omitted:
//=>x.join('').replace(new RegExp(x[x.length-1]+'$'),'.'+x[x.length-1])
}
alert(toFloat('1,223,455.223')); //=> 1223455.223
alert(toFloat('1.223.455,223')); //=> 1223455.223
// your numbers ;~)
alert(toFloat('3.123,56')); //=> 3123.56
alert(toFloat('3,123.56')); //=> 3123.56
What we do is try parsing using the culture of the user and if that doesn't work, parse it using an invariant culture.
I wouldn't know how to do it in javascript or vbscript exactly though.
I used KooiInc's answer but change it a bit, because it didn't reckon with some cases.
function toFloat(strNum) {
var full = strNum.split(/[.,]/);
if (full.length == 1) return parseFloat(strNum);
var back = full[full.length - 1];
var result = full.join('').replace(new RegExp(back + '$'), '.' + back);
return parseFloat(result);
}
Forbid using any thousands separator.
Give the user an example: "Reals should look like this: 3123.56 or 3123,56". Then simply change , to . and parse it.
You can always tell user that he did something wrong with a message like this:
"I don't understand what you mean by "**,**,**".
Please format numbers like "3123.56."