Does Number.toFixed() use locale conventions? - javascript

I am writing a JavaScript function that can perform decimal place manipulation on a string that was generated from a number using Number.toFixed(). Part of what I need to accomplish is to locate the location of the decimal point in the formatted string. I have begun to wonder, however, whether the toFixed() function will use locale specific formatting (e.g. '.' versus ',' for the decimal point). If that is the case, I can't merely search for the '.' character but may need to search for a comma or, perhaps, some other separator that is used in other locales.
In C++, I can use the numpunct locale facet to determine what character is used but I don't believe that there is any equivalent resource available in JavaScript. My question then becomes whether toFixed() is going to honour locale conventions and, if so, is there any way to recognise what convention is used on the browser host?

No, i does not. Only .toLocaleString() respects decimal separator. Neither Number('42,6') will return proper value assuming locale have ',' as decimal separator.

// You can always ask-
Number.decimalChar= (function(){
return (3/5).toLocaleString().charAt(1)
})()
alert(Number.decimalChar)

Related

Regex - creating an input/textarea that correctly interprets numbers

Im designing a conversion website where i perform calculations on inputted numbers and i need my input or textarea to receive and interpret numbers entered in different fashions
like:
Entry = 3,000,000.1111
Interpreted value = 3000000.1111
or
Entry = 3000000.1111
Interpreted value = 3000000.1111
and I want to include a second input for European decimal notation
(or if possible have the same input do both)
Entry = 3.000.000,1111 (comma acts a decimal, decimal as separator)
Interpreted value = 3000000.1111
I wonder how I could do this. I suspect from some of my research that I could use regex.
Also should i use an input or a textarea? I want to limit the size of the number to 40 places.
It seems the textarea Im currently using won't recognize any values after a comma when a comma is used. I realized this is due to parseFloat. So I need to remove the commas using .replace() before parsing. But what do I do in the instance of European notation where the comma IS the decimal point? I suspect I should use regex to identify if a number is in comma decimal notation or standard decimal point notation and then outline the appropriate replacement behavior based on that. Any ideas how to write regex to identify a number between .0000000001 and 1,000,000,000,000,000 by only the separator and decimal point? What about when the entry doesn't use either? 12000 for example. Any help with this would be appreciated. Using HTML5 and Javascript. I am not using a form and am new at this. This is my first web page so please be patient with my questions.
I was thinking about this:
input = //value from textarea as a string
if(/REGEX which determines that the structure of the number is N,NNN.NN/.test(input)){
input = input.replace(/\,/,""); //replace the commas with nothing
}
else if(/REGEX which determine that structure of the number is N.NNN,NN/.test(input){
input = input.replace(/\./,""); //replace the decimal point separators with nothing
input = input.replace(/\,/,".");//replace the comma decimal with a point decimal
}
else{
//input unchanged assuming is NNNN without decimal
}
number = parseFloat(input);
I want to keep the possibility open for them to enter large numbers and also to use numbers less than one to 10 decimal places. Thanks to those who contributed.
Best,RP
I believe this should handle everything:
^[1-9](?:\d{0,2}(?:([,.])\d{3})*|\d+)(?:(?!\1)[,.]\d+)?$
You're treading on complicated territory here. Also, the above RegEx does not allow for values less than "1".
Basically, the RegEx does the following:
Allows for no thousandths separators ("," or ".") but ensures if they are used that they occur in the correct places.
Allows for either "," or "." to be used as both thousandths/cents separators, but ensures that the cents separator is not the same as the thousandths separator.
Requires the string equivalent number to begin with any digit other than "0".
To implement this you could attach an event listener to your form element(s) and use JS to do a simple .test.
After reading further, I think I misinterpreted your goal originally. I assumed you simply wanted to validate these values with a RegEx. I also assumed you're trying to work with currency (ie. two decimal places). However, fret not! You can still utilize my original answer if you really want.
You mentioned input and textarea which are both form elements. You can attach a listener to these element(s) looking for the input, change, and/or keyup events. As a part of the callback you can run the .test method or some other functionality. Personally, I would rethink how you want to handle input. Also, what's your actual goal here? Do you really need to know the thousandths separator or keep track of it? Why not just disallow any characters other than the one decimal point/comma and digits?
Also, parsing numbers like .0000000001 as a float is a terrible idea. You will lose precision very quickly if you do any sort of calculations such as multiplication, division, power, etc. You're going to have to figure out a different method to do this like storing the number to the right separately and as integers instead then go from there.
I can help you if you describe what you're trying to do in better detail.

Getting the numeric value after the hyphen in a string

How can I extract and get just the numeric value after the hyphen in a string?
Here is the input string:
var x = "-2147467259"
After some processing.... return:
alert(2147467259)
How do I accomplish this?
You could replace away the hyphen:
alert(+x.replace("-", ""));
And yes, the + is important. It converts a string to a number; so you're removing the hypen by replacing it with nothing, and then essentially casting the result of that operation into a number. This operation will also work if no hyphen is present.
You could also use substr to achieve this:
alert(+x.substr(1));
You could also use parseInt to convert the string to a number (which will end up negative if a hyphen is persent), and then find its absolute value:
alert(Math.abs(parseInt(x, 10));
As Bergi notes, if you can be sure that the first character in the string is always a hyphen, you can simple return its negative, which will by default cast the value into a number and then perform the negative operation on it:
alert(-x);
You could also check to see if the number is negative or positive via a tertiary operator and then perform the respective operation on it to ensure that it is a positive Number:
x = x >= 0 ? +x : -x;
This may be cheaper in terms of performance than using Math.abs, but the difference will be minuscule either way.
As you can see, there really are a variety of ways to achieve this. I'd recommend reading up on JavaScript string functions and number manipulation in general, as well as examining JavaScript's Math object to get a feel for what tools are available to you when you go to solve a problem.
How about:
Math.abs(parseInt("-2147467259"))
Or
"-2147467259".replace('-','')
or
"-2147467259".replace(/\-/,'')
#1 option is converting the string to numbers. The #2 approach is removing all - from the string and the #3 option even though it will not be necessary on this example uses Regular Expression but I wanted to show the possibility of using RegEx in replace situations.
If you need a number as the final value #1 is your choice if you need strings #2 is your choice.

JavaScript parseFloat in Different Cultures

I have a question about the default behavior of JavaScript's parseFloat function in different parts of the world.
In the US, if you call parseFloat on a string "123.34", you'd get a floating point number 123.34.
If I'm developing code in say Sweden or Brazil and they use a comma instead of a period as the decimal separator, does the parseFloat function expect "123,34" or "123.34".
Please note that I'm not asking how to parse a different culture's number format in the US. I'm asking does parseFloat in Sweden or Brazil behave the same way it does inside the US, or does it expect a number in its local format? Or to better think about this, does a developer in Brazil/Sweden have to convert strings to English format before it can use parseFloat after extracting text from a text box?
Please let me know if this doesn't make sense.
parseFloat doesn't use your locale's definition, but the definition of a decimal literal.
It only parses . not ,
I'm brazilian and I have to replace comma with dot before parsing decimal numbers.
parseFloat specification
No, parseFloat is specified to parse DecimalLiterals, which use the dot as decimal separator. It does not depend on the current environment's locale settings.
It’s not just Sweden/Brazil. F.ex in US they often add commas in large numbers, like $5,762,325.25.
The parseFloat function essentially deals with decimals, not locale strings.
In general, JavaScript can sometimes convert generic strings/numbers/dates to locale-friendly formats, but not the other way around.
Complementing the answer given by FrancescoMM, you must use regex for really big numbers. String.replace using string as a parameter will replace only the first occurrence. So 999.999.999,99 becomes 999999.999.99
stringNum.replace(/\./g, "").replace(/\,/g, ".")
Source:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace
If you are sure it is in Brasilian format, just convert the number to US format before parsing.
function parseItalianNumber(stringNum) {
return parseFloat(stringNum.replaceAll(".","").replaceAll(",","."));
}
in Italy we also use . as a thousands separator. This removes any thousands separators, just in case (you do not want many dots around), and then converts the comma to a dot, before calling parseFloat.

How to prevent removing decimal point when parsing JSON?

If you do this...
var parsed = JSON.parse('{"myNum":0.0}') ;
Then when you look at parsed.myNum, you just get 0. (Fair enough.)
If you do parsed.myNum.toString(), you get "0".
Basically, I'm looking for a way to turn this into the string "0.0".
Obviously, in real life I don't control the JSON input, I get the JSON from a web service... I want to parse the JSON using the browser's JSON parser, and to be able to recognise the difference between the number values 0 and 0.0.
Is there any way to do this, short of manually reading the JSON string? That's not really possible in this case, I need to use the browser's native JSON parser, for speed. (This is for a Chrome extension by the way; no need to worry about it working in other browsers.)
There's no way to get the number of digits from JSON.parse or eval. Even if IBM's decimal proposal had been adopted by the EcmaScript committee, the number is still going to be parsed to an IEEE 754 float.
Take a look a http://code.google.com/p/json-sans-eval/source/browse/trunk/src/json_sans_eval.js for a simple JSON parser that you can modify to keep precision info.
If 0.0 is not enclosed in quotes in your JSON (i.e. it's a number and not a string), then there's no way to distinguish it from 0, unless you write your own JSON parser.
... parsed.myNum.toFixed( 1 ) ...
where 1 is number of decimal places
Edit: parsed.myNum is number, parsed.myNym.toFixed( 1 ) would be string
Edit2: in this case you need to pass value as string {"myNum":'0.0'} and parsed when calculations is needed or detect decimal separator, parsed number, and use decimal separator position when string is needed
It shouldn't matter, 00000.00000 is 0 if you try JSON.parse('{"myNum":0.00001}') you'll see a value of { myNum=0.0001 } If you really need it to hold the decimal you'll need to keep it a string JSON.parse('{"myNum":"0.0"}')

What is the decimal separator symbol in JavaScript?

A thought struck me as I was writing a piece of JavaScript code that processed some floating point values. What is the decimal point symbol in JavaScript? Is it always .? Or is it culture-specific? And what about .toFixed() and .parseFloat()? If I'm processing a user input, it's likely to include the local culture-specific decimal separator symbol.
Ultimately I'd like to write code that supports both decimal points in user input - culture-specific and ., but I can't write such a code if I don't know what JavaScript expects.
Added: OK, Rubens Farias suggests to look at similar question which has a neat accepted answer:
function whatDecimalSeparator() {
var n = 1.1;
n = n.toLocaleString().substring(1, 2);
return n;
}
That's nice, it lets me get the locale decimal point. A step towards the solution, no doubt.
Now, the remaining part would be to determine what the behavior of .parseFloat() is. Several answers point out that for floating point literals only . is valid. Does .parseFloat() act the same way? Or might it require the local decimal separator in some browser? Are there any different methods for parsing floating point numbers as well? Should I roll out my own just-to-be-sure?
According to the specification, a DecimalLiteral is defined as:
DecimalLiteral ::
DecimalIntegerLiteral . DecimalDigitsopt ExponentPartopt
. DecimalDigits ExponentPartopt
DecimalIntegerLiteral ExponentPartopt
and for satisfying the parseFloat argument:
Let inputString be ToString(string).
Let trimmedString be a substring of inputString consisting of the leftmost character that is not a StrWhiteSpaceChar and all characters to the right of that character.(In other words, remove leading white space.)
If neither trimmedString nor any prefix of trimmedString satisfies the syntax of a StrDecimalLiteral (see 9.3.1), return NaN.
Let numberString be the longest prefix of trimmedString, which might be trimmedString itself, that satisfies the syntax of a StrDecimalLiteral.
Return the Number value for the MV
So numberString becomes the longest prefix of trimmedString that satisfies the syntax of a StrDecimalLiteral, meaning the first parseable literal string number it finds in the input. Only the . can be used to specify a floating-point number. If you're accepting inputs from different locales, use a string replace:
function parseLocalNum(num) {
return +(num.replace(",", "."));
}
The function uses the unary operator instead of parseFloat because it seems to me that you want to be strict about the input. parseFloat("1ABC") would be 1, whereas using the unary operator +"1ABC" returns NaN. This makes it MUCH easier to validate the input. Using parseFloat is just guessing that the input is in the correct format.
use:
theNumber.toLocaleString();
to get a properly formatted string with the right decimal and thousands separators
As far as I'm aware, javascript itself only knows about the . separator for decimals. At least one person whose judgement I trust on JS things concurs:
http://www.merlyn.demon.co.uk/js-maths.htm#DTS

Categories

Resources