Can someone help understand why my session value changed for a particular value, 03375?
My MVC controller code:
Session["something"] = "03375";
My view js code:
$(function(){
alert(#Session["something"].ToString());
});
Result: js alerts 1789. Why???
It works for other values except. Here is a fiddle https://dotnetfiddle.net/zLdyO8
This has nothing to do with asp.net session. If you do this in your page
console.log(03375);
You will get 1789
Why is this happening ?
Because when browser's javascript runtime sees a number starting with 0 prefix, it thinks it is octal representation of the number. In fact 03375 is the octal equivalent of 1789. So your browser is basically converting the octal value
to it's decimal equivalent and giving you 1789 (browsers usually parse the number to decimal representation)
From mdn,
Note that decimal literals can start with a zero (0) followed by
another decimal digit, but if every digit after the leading 0 is
smaller than 8, the number gets parsed as an octal number.
This means, if you are trying
console.log(09375);
It will print,9375 !!!
To handle your case, the ideal solution is to set the correct type value. For example, if you are passing a numeric value, simply set the numeric value instead of the string version with leading zero..
Session["something"] = "3375";
Or even better
Session["something"] = 3375;
Then in the client side,
alert(#Session["something"]);
If you absolutely want to keep the 0 prefix, while setting the session value, but you want the value as number at client side, you can read it in a string and then use parseInt to convert it to a number type
var r = '#Session["something"].ToString()';
alert(r); // the string with leading 0
var n = parseInt(r);
alert(n); // the number
alert(typeof(n));
Related
I'm taking a numerical input as an argument and was just trying to account for leading zeroes. But it seems javascript converts the number into octal before I can do anything to the number. The only way to work around it so far is if I pass the number as a string initially but I was hoping there'd be another way to convert it after it is passed? So far tried (using 017 which alerted me to the octal behaviour):
017.toString(10) // 15
parseInt(017,10) // 15
017 + "" //15
new Number(017) //15
new Number('017') //17
parseInt('017', 10) // 17
So given
function(numb) {
if (typeof numb === number) {
// remove leading zeroes and convert to decimal
}
else {
// use parseInt
}
}
'use strict' also doesn't seem to solve this as some older posts have suggested. Any ideas?
If you take "numerical input", you should always definitely guaranteed have a string. There's no input method in this context that I know that returns a Number. Since you receive a string, parseInt(.., 10) will always be sufficient. 017 is only interpreted as octal if written literally as such in source code (or when missing the radix parameter to parseInt).
If for whatever bizarre reason you do end up with a decimal interpreted as octal and you want to reverse-convert the value back to a decimal, it's pretty simple: express the value in octal and re-interpret that as decimal:
var oct = 017; // 15
parseInt(oct.toString(8), 10) // 17
Though because you probably won't know whether the input was or wasn't interpreted as octal originally, this isn't something you should have to do ever.
JavaScript interprets all numbers beginning with a 0, and containing all octal numerals as octals - eg 017 would be an octal but 019 wouldn't be. If you want your number as a decimal then either
1. Omit the leading 0.
2. Carry on using parseInt().
The reason being is that JavaScript uses a few implicit conversions and it picks the most likely case based on the number. It was decided in JavaScript that a leading 0 was the signal that a number is an octal. If you need that leading 0 then you have to accept that rule and use parseInt().
Source
If you type numbers by hand to script then not use leading zeros (which implicity treat number as octal if it is valid octal - if not then treat it as decimal). If you have number as string then just use + operator to cast to (decimal) number.
console.log(+"017")
if (021 < 019) console.log('Paradox');
The strict mode will not allow to use zero prefix
'use strict'
if (021 < 019) console.log('Paradox');
In my code, the value of a particular var can originate from any one of a number of different json sources. For some of those sources, the json element concerned will be a string (e.g. "temp": "10.2"), while for other sources the json element will already be a float (e.g. "temp": 10.2).
Does it do any harm (is anything likely to break) if I just pass the json element (from whatever source) through a parseFloat(), even if it's already a float? It seems to work; I'm just thinking about good/bad practice and possible breakage in future or on a different platform.
Thanks.
You should be able to call parseFloat() on a float or a string without any problems. If it is a float already, it's converted to a string first, and then to a float again, so it's a little less efficient, but it shouldn't matter too much.
You should still check the result for NaN, in case there's something unexpected in the data.
The most appropriate method to convert any datatype to a number is to use the Number function:
In a non-constructor context (i.e., without the new operator),
Number can be used to perform a type conversion.
Number("1234") // 1234
Number(1234) // 1234
This method differs from parseFloat in these ways at least:
Number function does not perform "double-conversion" if the input is already a number (ref)
Parse float converts the input to a string then extracts the number (ref)
Number function returns common sense values for most datatypes e.g. Number(true) yields 1
Parse float uses the string value of input so parseFloat(true) tries to parse number from "true" and yields NaN
Number function fails when input string is an invalid number e.g. Number("123abc") yields NaN
Parse float tries to parse as much of a number as possible e.g. parseFloat("123abc") yields 123
If you are sure the value is always a valid number, you should use Number(stringOrNumber).
If you need some additional safety using parseFloat() you could also write your own function which is also performance optimized:
function toFloat(value) {
return typeof value === 'number' ? value : parseFloat(value);
}
I also created a jsPerf test case that shows the performance is >30% better than the plain parseFloat() for a 1:1 ratio between strings and numbers as input values.
Nope there is no problem with passing a number to it
MDN says as long as it can be converted to a number, nothing breaking should happen.
If the first character cannot be converted to a number, parseFloat returns NaN.
As an alternative, you could use the unary operator + which does basically the same thing as parseFloat and also returns NaN if it didn't work.
For instance:
var myFloat = +('10.5');
var myOtherFloat = parseFloat('10.5', 10);
var alreadyAFloat = parseFloat(10.5, 10);
console.log(myFloat === myOtherFloat && myOtherFloat === alreadyAFloat); // true
Wether it's a float or a String using parseFloat() is much safer to avoid all kind of errors.
As you said it will always work, but if you enforce it to be a float you will avoid getting any Exception.
For Example:
Both parseFloat('10.2', 10) and parseFloat(10.2, 10) will work
perfectly and will give you the same result which is 10.2.
Personally I can't see this being a problem what so ever, to be honest I would always use the parsefloat() for one reason, and that is safety. You can never be to sure what may happen, so always predict the worse :D
If I define a new Object in javascript, with var myobject = {} I will have an empty object, as expected. However, I fail to understand the logic behind this. Note that it all works, but I don't get it, more a tease than anything else:
var myobject = {}; // Object{}
myobject[001] = "001"; // Object {1: "001"}, So 001 turns to 1
myobject[0099999] = "0099999"; // Object {1: "001", 99999: "0099999"}
//Last line only makes sense after this one (shortened version)▼
myobject[0023122] = "0023122" // Object {... 9810: "0023122" ...}
I know I can't access those properties with myobject.0023122 since they start with a digit, but I can't by doing this myobject['0023122'] either so I'm assuming that the number 0023122 is transformed to the property with a key 9810 since I can do myobject['9810'] and get the result.
What's fascinating about this is that I can do myobject[99999] and myobject['99999'] so javascript didn't need to reject my key although I lose my leading zeros. I'm not talking about what's wrong and right to do, just what is the reason for the number 0023122 to be converted to 9810 while even 0023123 converts gracefully to 23123 just as 0099999 converts to 99999
I assumed it was too big of a number, that's why I tried with one even bigger.
If you remove the leading zeros, the key becomes "23123"
Javascript supports octal numbers:
Positive octal numbers must begin with 0 (zero) followed by octal digit(s).
0023122 (in octal) is 9810 (in decimal)
So any number that has all digits less than 8, but starts with a 0, will be converted to octal.
If it has an 8 or 9, it will get truncated if it starts with a 0.
091 -> 91
but
071 -> 57
Of course, if you use string keys, nothing to worry about:
myobject["001111"] = "001111"
myobject[001111] = 585
If a number in JS starts with a zero, it's assumed to be octal, which is why the key is converted. myobject[0099999] might actually cause an error as it isn't a valid octal number because it contains 9s (but this may vary depending on browser/interpreter)
In the code myobject[0023122] = "0023122"; the value used as an index for object is evaluated as a integer primitive.
The prefix of 0 causes it to be interpreted as an OctalIntegerLiteral, meaning that 0023122 is evaluated as octal. Had it been 23122 it would be evaluated as an IntegerLiteral. 0x23122 would cause it to be evaluated as a HexIntegerLiteral.
See more here: http://www.ecma-international.org/ecma-262/5.1/#sec-7.8.3
I have the problem that when i round a number to 2 decimals the parseFloat() function removes .00 from the number. I have tried
var num = parseFloat(Math.round(19 * 100) / 100).toFixed(2);
The return: num="19.00"
The return i need: num = 19.00
I know 19 = 19.00, but i am using a service that always require two decimals .00
The function returns a string with the right value. When i parse it to float the .00 is removed.
You cannot get 19.00 as float, only as string, because numbers always remove trailing zeros.
Maybe you can show us a bit more code to get an idea, there you need these trailing zeros?
Numbers do and can not hold information about their representation. They are only a numerical value.
When you display a number using window.alert, console.log or similar, you are not looking at a number, but at a string. Those display functions convert numbers to strings before displaying them. Number.toFixed also converts numbers into strings, with the difference being that it rounds them to two decimal places, so you end up with another representation of the same number.
What I am trying to say is that to display a number, you cannot get around converting it to a string. Whether you do it explicitly or the display function does it for you. When you send the number to the service that you are using, you are probably also sending a string (JSON, XML, etc. are always strings once you send them). If you need the value of the number for calculations, use it, then convert it in the end. No matter how, you have to do it in the end if you want those 0's at the end.
I have a button where in the code behind I add a onclick and I pass a unique ID which will be passed to the js function. The id starts with a 0.
It wasn't working and eventually I figured out that the number, id, it was passing was wrong...
Ie. see this: js fiddle
It works with a ' at the start and end of the number. Just wondering why 013 turns to 11. I did some googling and couldn't find anything...
Cheers
Robin
Edit:
Thanks guys. Yep understand now.
As in this case the 0 at the start has a meaning, here the recipient ID in a mailing list, I will use '013' instead of just 013, i.e. a string. I can then split the values in js as each of the 3 values represents a different id which will always be only 1 character long, i.e. 0-9.
A numeric literal that starts with a 0 is treated as an octal number. So 13 from base 8 is 11 in base 10...
Octal numeric literals have been deprecated, but still work if you are not in strict mode.
(You didn't ask, but) A numeric literal that starts with 0x is treated as hexadecimal.
More info at MDN.
In your demo the parameter is called id, which implies you don't need to do numerical operations on it - if so, just put it in quotes and use it as a string.
If you need to be able to pass a leading zero but still have the number treated as base 10 to do numerical operations on it you can enclose it in quotes to pass it as a string and then convert the string to a number in a way that forces base 10, e.g.:
something('013');
function something(id){
alert(+id); // use unary plus operator to convert
// OR
alert(parseInt(id,10)); // use parseInt() to convert
}
Demo: http://jsfiddle.net/XYa6U/5/
013 is octal, not decimal, it's equal 11 in decimal
You should note that 013 starts with a 0. In Javascript, this causes the number to be considered octal. In general you'll want to use the decimal, and hexadecimal number systems. Occasionally though, octal numbers are useful, as this question shows.
I hope this helps! :)
If the first digit of a number is a zero, parseInt interprets the number as an octal.
You can specify a base of ten like this:
parseInt(numberString, 10)
You could also remove such zeros with a regex like this (the result will be a string):
numberString.replace(/^0+/g, '');